diff --git a/frameworks/innerkits/file_access/BUILD.gn b/frameworks/innerkits/file_access/BUILD.gn index 79a2c34095416004d5280e1313acad1497097864..30d9b2ccc1021e5ea0144b1162d799d2d41a407c 100644 --- a/frameworks/innerkits/file_access/BUILD.gn +++ b/frameworks/innerkits/file_access/BUILD.gn @@ -47,11 +47,17 @@ config("ability_public_config") { } ohos_shared_library("file_access_extension_ability_kit") { - include_dirs = [] + include_dirs = [ "//foundation/ability/ability_runtime/interfaces/kits/native/appkit/ability_runtime/context" ] sources = [ "src/file_access_ext_ability.cpp", + "src/file_access_ext_connection.cpp", + "src/file_access_ext_proxy.cpp", + "src/file_access_ext_stub.cpp", + "src/file_access_ext_stub_impl.cpp", + "src/file_access_helper.cpp", "src/js_file_access_ext_ability.cpp", + "src/napi_common_fileaccess.cpp", ] configs = [ ":ability_config" ] public_configs = [ diff --git a/frameworks/innerkits/file_access/include/file_access_ext_ability.h b/frameworks/innerkits/file_access/include/file_access_ext_ability.h index 255a01f98b82edaebabe35e1ff2bf7ea54b333f3..709f66c1f0659b2464026824ae4921befaaf4c71 100644 --- a/frameworks/innerkits/file_access/include/file_access_ext_ability.h +++ b/frameworks/innerkits/file_access/include/file_access_ext_ability.h @@ -17,6 +17,7 @@ #define FILE_EXT_ABILITY_H #include "extension_base.h" +#include "file_access_extension_info.h" namespace OHOS { namespace AbilityRuntime { @@ -37,6 +38,22 @@ public: const sptr &token) override; static FileAccessExtAbility* Create(const std::unique_ptr& runtime); + + virtual int OpenFile(const Uri &uri, int flags); + virtual int CreateFile(const Uri &parent, const std::string &displayName, Uri &newFile); + virtual int Mkdir(const Uri &parent, const std::string &displayName, Uri &newFile); + virtual int Delete(const Uri &sourceFile); + virtual int Move(const Uri &sourceFile, const Uri &targetParent, Uri &newFile); + virtual int Rename(const Uri &sourceFile, const std::string &displayName, Uri &newFile); + + virtual std::vector ListFile(const Uri &sourceFile); + virtual std::vector GetRoots(); + + /** + * @brief Set a creator function. + * + * @param creator The function for create a file extension ability. + */ static void SetCreator(const CreatorFunc& creator); private: static CreatorFunc creator_; diff --git a/frameworks/innerkits/file_access/include/file_access_ext_ability_module_loader.h b/frameworks/innerkits/file_access/include/file_access_ext_ability_module_loader.h index fad8b9cf8c79e7cc960da40b00910b87a2c5660a..598c3bb12e2e371f76d5f8380ff5487d8d63a95f 100644 --- a/frameworks/innerkits/file_access/include/file_access_ext_ability_module_loader.h +++ b/frameworks/innerkits/file_access/include/file_access_ext_ability_module_loader.h @@ -1,33 +1,33 @@ -/* - * Copyright (c) 2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef FILE_EXT_ABILITY_MODULE_LOADER_H -#define FILE_EXT_ABILITY_MODULE_LOADER_H - -#include "extension_module_loader.h" -namespace OHOS { -namespace FileAccessFwk { -using namespace AbilityRuntime; -class FileAccessExtAbilityModuleLoader : public ExtensionModuleLoader, - public Singleton { - DECLARE_SINGLETON(FileAccessExtAbilityModuleLoader); - -public: - virtual Extension *Create(const std::unique_ptr& runtime) const override; - virtual std::map GetParams() override; -}; -} // namespace FileAccessFwk -} // namespace OHOS +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FILE_EXT_ABILITY_MODULE_LOADER_H +#define FILE_EXT_ABILITY_MODULE_LOADER_H + +#include "extension_module_loader.h" +namespace OHOS { +namespace FileAccessFwk { +using namespace AbilityRuntime; +class FileAccessExtAbilityModuleLoader : public ExtensionModuleLoader, + public Singleton { + DECLARE_SINGLETON(FileAccessExtAbilityModuleLoader); + +public: + virtual Extension *Create(const std::unique_ptr& runtime) const override; + virtual std::map GetParams() override; +}; +} // namespace FileAccessFwk +} // namespace OHOS #endif // FILE_EXT_ABILITY_MODULE_LOADER_H \ No newline at end of file diff --git a/frameworks/innerkits/file_access/include/file_access_ext_connection.h b/frameworks/innerkits/file_access/include/file_access_ext_connection.h new file mode 100644 index 0000000000000000000000000000000000000000..e47b0cffd9a9cd1cb0abdcc1414f3caf827135d0 --- /dev/null +++ b/frameworks/innerkits/file_access/include/file_access_ext_connection.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FILE_EXT_CONNECTION_H +#define FILE_EXT_CONNECTION_H + +#include + +#include "ability_connect_callback_stub.h" +#include "event_handler.h" +#include "ifile_access_ext_base.h" +#include "want.h" + +namespace OHOS { +namespace FileAccessFwk { +class FileAccessExtConnection : public AAFwk::AbilityConnectionStub { +public: + FileAccessExtConnection() = default; + virtual ~FileAccessExtConnection() = default; + + static sptr GetInstance(); + + void OnAbilityConnectDone( + const AppExecFwk::ElementName &element, const sptr &remoteObject, int resultCode) override; + + void OnAbilityDisconnectDone(const AppExecFwk::ElementName &element, int resultCode) override; + + void ConnectFileExtAbility(const AAFwk::Want &want, const sptr &token); + + void DisconnectFileExtAbility(); + + bool IsExtAbilityConnected(); + + sptr GetFileExtProxy(); + +private: + static sptr instance_; + static std::mutex mutex_; + std::atomic isConnected_ = {false}; + sptr fileExtProxy_; +}; +} // namespace FileAccessFwk +} // namespace OHOS +#endif // FILE_EXT_CONNECTION_H diff --git a/frameworks/innerkits/file_access/include/file_access_ext_proxy.h b/frameworks/innerkits/file_access/include/file_access_ext_proxy.h new file mode 100644 index 0000000000000000000000000000000000000000..51437ecfc4d7ae7b5a5a2a52a244db0a09a8591e --- /dev/null +++ b/frameworks/innerkits/file_access/include/file_access_ext_proxy.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FILE_EXT_PROXY_H +#define FILE_EXT_PROXY_H + +#include + +#include "file_access_extension_info.h" +#include "ifile_access_ext_base.h" + +namespace OHOS { +namespace FileAccessFwk { +class FileAccessExtProxy : public IRemoteProxy { +public: + explicit FileAccessExtProxy(const sptr& remote) : IRemoteProxy(remote) {} + + virtual ~FileAccessExtProxy() {} + + virtual int OpenFile(const Uri &uri, int flags) override; + virtual int CreateFile(const Uri &parent, const std::string &displayName, Uri &newFile) override; + virtual int Mkdir(const Uri &parent, const std::string &displayName, Uri &newFile) override; + virtual int Delete(const Uri &sourceFile) override; + virtual int Move(const Uri &sourceFile, const Uri &targetParent, Uri &newFile) override; + virtual int Rename(const Uri &sourceFile, const std::string &displayName, Uri &newFile) override; + + virtual std::vector ListFile(const Uri &sourceFile) override; + virtual std::vector GetRoots() override; +private: + static inline BrokerDelegator delegator_; +}; +} // namespace FileAccessFwk +} // namespace OHOS +#endif // FILE_EXT_PROXY_H + diff --git a/frameworks/innerkits/file_access/include/file_access_ext_stub.h b/frameworks/innerkits/file_access/include/file_access_ext_stub.h new file mode 100644 index 0000000000000000000000000000000000000000..ddcb2b7cb7d0f78768f3ff064869715bd10d72d0 --- /dev/null +++ b/frameworks/innerkits/file_access/include/file_access_ext_stub.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FILE_EXT_STUB_H +#define FILE_EXT_STUB_H + +#include +#include + +#include "file_access_extension_info.h" +#include "ifile_access_ext_base.h" + +namespace OHOS { +namespace FileAccessFwk { +class FileAccessExtStub : public IRemoteStub { +public: + FileAccessExtStub(); + ~FileAccessExtStub(); + int OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel& reply, MessageOption& option) override; +private: + ErrCode CmdOpenFile(MessageParcel &data, MessageParcel &reply); + ErrCode CmdCreateFile(MessageParcel &data, MessageParcel &reply); + ErrCode CmdMkdir(MessageParcel &data, MessageParcel &reply); + ErrCode CmdDelete(MessageParcel &data, MessageParcel &reply); + ErrCode CmdMove(MessageParcel &data, MessageParcel &reply); + ErrCode CmdRename(MessageParcel &data, MessageParcel &reply); + + ErrCode CmdListFile(MessageParcel &data, MessageParcel &reply); + ErrCode CmdGetRoots(MessageParcel &data, MessageParcel &reply); + + using RequestFuncType = int (FileAccessExtStub::*)(MessageParcel &data, MessageParcel &reply); + std::map stubFuncMap_; +}; +} // namespace FileAccessFwk +} // namespace OHOS +#endif // FILE_EXT_STUB_H + diff --git a/frameworks/innerkits/file_access/include/file_access_ext_stub_impl.h b/frameworks/innerkits/file_access/include/file_access_ext_stub_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..4abc888f9b55885bca6acdb86bd44c6e96303947 --- /dev/null +++ b/frameworks/innerkits/file_access/include/file_access_ext_stub_impl.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FILE_EXT_STUB_IMPL_H +#define FILE_EXT_STUB_IMPL_H + +#include +#include "file_access_ext_stub.h" +#include "file_access_extension_info.h" +#include "file_access_ext_ability.h" +#include "native_engine/native_value.h" + +namespace OHOS { +namespace FileAccessFwk { +class FileAccessExtStubImpl : public FileAccessExtStub { +public: + explicit FileAccessExtStubImpl(const std::shared_ptr& extension, napi_env env) + : extension_(extension) {} + + virtual ~FileAccessExtStubImpl() {} + + int OpenFile(const Uri &uri, int flags) override; + int CreateFile(const Uri &parent, const std::string &displayName, Uri &newFile) override; + int Mkdir(const Uri &parent, const std::string &displayName, Uri &newFile) override; + int Delete(const Uri &sourceFile) override; + int Move(const Uri &sourceFile, const Uri &targetParent, Uri &newFile) override; + int Rename(const Uri &sourceFile, const std::string &displayName, Uri &newFile) override; + + std::vector ListFile(const Uri &sourceFileUri) override; + std::vector GetRoots() override; +private: + std::shared_ptr GetOwner(); + +private: + std::shared_ptr extension_; +}; +} // namespace FileAccessFwk +} // namespace OHOS +#endif // FILE_EXT_STUB_IMPL_H diff --git a/frameworks/innerkits/file_access/include/file_access_extension_info.h b/frameworks/innerkits/file_access/include/file_access_extension_info.h new file mode 100644 index 0000000000000000000000000000000000000000..c117d40a36ca63d9e6bff051f27e951a9ac56acd --- /dev/null +++ b/frameworks/innerkits/file_access/include/file_access_extension_info.h @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef FILE_EXTENSION_INFO_H +#define FILE_EXTENSION_INFO_H + +#include +#include + +#include "parcel.h" +#include "uri.h" + +namespace OHOS { +namespace FileAccessFwk { +struct FileInfo : public virtual OHOS::Parcelable { +public: + Uri uri = Uri(""); + std::string fileName; + std::string mode; + int64_t size {0}; + int64_t mtime {0}; + std::string mimeType; + + bool ReadFromParcel(Parcel &parcel) + { + std::unique_ptr uriInfo(parcel.ReadParcelable()); + if (uriInfo == nullptr) { + return false; + } + uri = *uriInfo; + + fileName = parcel.ReadString(); + mode = parcel.ReadString(); + size = parcel.ReadUint64(); + mtime = parcel.ReadInt64(); + mimeType = parcel.ReadString(); + return true; + } + virtual bool Marshalling(Parcel &parcel) const override + { + if (!parcel.WriteParcelable(&uri)) { + return false; + } + if (!parcel.WriteString(fileName)) { + return false; + } + if (!parcel.WriteString(mode)) { + return false; + } + if (!parcel.WriteUint64(size)) { + return false; + } + if (!parcel.WriteInt64(mtime)) { + return false; + } + if (!parcel.WriteString(mimeType)) { + return false; + } + return true; + } + static FileInfo *Unmarshalling(Parcel &parcel) + { + FileInfo *info = new (std::nothrow) FileInfo(); + if (info == nullptr) { + return nullptr; + } + + if (!info->ReadFromParcel(parcel)) { + delete info; + info = nullptr; + } + return info; + } +}; + +struct DeviceInfo : public virtual OHOS::Parcelable { +public: + Uri uri = Uri(""); + std::string displayName; + std::string deviceId; + uint32_t flags {0}; + + bool ReadFromParcel(Parcel &parcel) + { + std::unique_ptr uriInfo(parcel.ReadParcelable()); + if (uriInfo == nullptr) { + return false; + } + uri = *uriInfo; + + displayName = parcel.ReadString(); + deviceId = parcel.ReadString(); + flags = parcel.ReadUint32(); + return true; + } + virtual bool Marshalling(Parcel &parcel) const override + { + if (!parcel.WriteParcelable(&uri)) { + return false; + } + if (!parcel.WriteString(displayName)) { + return false; + } + if (!parcel.WriteString(deviceId)) { + return false; + } + if (!parcel.WriteUint32(flags)) { + return false; + } + return true; + } + static DeviceInfo *Unmarshalling(Parcel &parcel) + { + DeviceInfo *info = new (std::nothrow) DeviceInfo(); + if (info == nullptr) { + return nullptr; + } + + if (!info->ReadFromParcel(parcel)) { + delete info; + info = nullptr; + } + return info; + } +}; + +const uint32_t FLAG_SUPPORTS_THUMBNAIL = 1; +const uint32_t FLAG_SUPPORTS_WRITE = 1 << 1; +const uint32_t FLAG_SUPPORTS_READ = 1 << 2; +const uint32_t FLAG_SUPPORTS_DELETE = 1 << 3; +const uint32_t FLAG_SUPPORTS_RENAME = 1 << 4; +const uint32_t FLAG_SUPPORTS_MOVE = 1 << 5; +} // namespace FileAccessFwk +} // namespace OHOS +#endif // FILE_EXTENSION_INFO_H \ No newline at end of file diff --git a/frameworks/innerkits/file_access/include/file_access_helper.h b/frameworks/innerkits/file_access/include/file_access_helper.h new file mode 100644 index 0000000000000000000000000000000000000000..53fdddc5169cd13fcc73f698fddb2216bd5fa205 --- /dev/null +++ b/frameworks/innerkits/file_access/include/file_access_helper.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FILE_ACCESS_HELPER_H +#define FILE_ACCESS_HELPER_H + +#include +#include + +#include "context.h" +#include "file_access_ext_connection.h" +#include "file_access_extension_info.h" +#include "hilog_wrapper.h" +#include "ifile_access_ext_base.h" +#include "uri.h" +#include "want.h" + +using Uri = OHOS::Uri; + +namespace OHOS { +namespace FileAccessFwk { +using string = std::string; +class FileAccessHelper final : public std::enable_shared_from_this { +public: + ~FileAccessHelper() = default; + + static std::shared_ptr Creator(const std::shared_ptr &context, + const AAFwk::Want &want); + + static std::shared_ptr Creator(const sptr &token, const AAFwk::Want &want); + bool GetProxy(); + bool Release(); + int OpenFile(Uri &uri, int flags); + int CreateFile(Uri &parent, const std::string &displayName, Uri &newFile); + int Mkdir(Uri &parent, const std::string &displayName, Uri &newDir); + int Delete(Uri &selectFile); + int Move(Uri &sourceFile, Uri &targetParent, Uri &newFile); + int Rename(Uri &sourceFile, const std::string &displayName, Uri &newFile); + + std::vector ListFile(Uri &sourceFile); + std::vector GetRoots(); +private: + FileAccessHelper(const std::shared_ptr &context, const AAFwk::Want &want, + const sptr &fileAccessExtProxy); + FileAccessHelper(const sptr &token, + const AAFwk::Want &want, const sptr &fileAccessExtProxy); + void AddFileAccessDeathRecipient(const sptr &token); + void OnSchedulerDied(const wptr &remote); + + sptr token_ = {}; + AAFwk::Want want_ = {}; + sptr fileAccessExtProxy_ = nullptr; + bool isSystemCaller_ = false; + sptr callerDeathRecipient_ = nullptr; + sptr fileAccessExtConnection_ = nullptr; +}; + +class FileAccessDeathRecipient : public IRemoteObject::DeathRecipient { +public: + using RemoteDiedHandler = std::function &)>; + + explicit FileAccessDeathRecipient(RemoteDiedHandler handler); + + virtual ~FileAccessDeathRecipient(); + + virtual void OnRemoteDied(const wptr &remote); + +private: + RemoteDiedHandler handler_; +}; +} // namespace FileAccessFwk +} // namespace OHOS +#endif // FILE_ACCESS_HELPER_H diff --git a/frameworks/innerkits/file_access/include/ifile_access_ext_base.h b/frameworks/innerkits/file_access/include/ifile_access_ext_base.h new file mode 100644 index 0000000000000000000000000000000000000000..5c79a87b62b8fea0fa0cdb801b4171aeacd876d4 --- /dev/null +++ b/frameworks/innerkits/file_access/include/ifile_access_ext_base.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef I_FILE_EXT_BASE_H +#define I_FILE_EXT_BASE_H + +#include +#include +#include +#include + +#include "file_access_extension_info.h" +#include "uri.h" + +namespace OHOS { +namespace FileAccessFwk { +class IFileAccessExtBase : public IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.FileAccessFwk.IFileAccessExtBase"); + + enum { + CMD_OPEN_FILE = 1, + CMD_CREATE_FILE = 2, + CMD_MKDIR = 3, + CMD_DELETE = 4, + CMD_MOVE = 5, + CMD_RENAME = 6, + CMD_LIST_FILE = 7, + CMD_GET_ROOTS = 8 + }; + + virtual int OpenFile(const Uri &uri, int flags) = 0; + virtual int CreateFile(const Uri &parent, const std::string &displayName, Uri &newFile) = 0; + virtual int Mkdir(const Uri &parent, const std::string &displayName, Uri &newFile) = 0; + virtual int Delete(const Uri &sourceFile) = 0; + virtual int Move(const Uri &sourceFile, const Uri &targetParent, Uri &newFile) = 0; + virtual int Rename(const Uri &sourceFile, const std::string &displayName, Uri &newFile) = 0; + + virtual std::vector ListFile(const Uri &sourceFile) = 0; + virtual std::vector GetRoots() = 0; +}; +} // namespace FileAccessFwk +} // namespace OHOS +#endif // I_FILE_EXT_BASE_H diff --git a/frameworks/innerkits/file_access/include/js_file_access_ext_ability.h b/frameworks/innerkits/file_access/include/js_file_access_ext_ability.h index 8ac3b18d35db49103380f3f18940af83da2ecee7..9a0eca63865d1951f9c475b11313ba08219706f3 100644 --- a/frameworks/innerkits/file_access/include/js_file_access_ext_ability.h +++ b/frameworks/innerkits/file_access/include/js_file_access_ext_ability.h @@ -17,14 +17,32 @@ #define JS_FILE_EXT_ABILITY_H #include "file_access_ext_ability.h" - +#include "file_access_extension_info.h" #include "js_runtime.h" +#include "napi_common_fileaccess.h" #include "native_engine/native_reference.h" #include "native_engine/native_value.h" namespace OHOS { namespace FileAccessFwk { using namespace AbilityRuntime; + +struct ThreadLockInfo { + std::mutex fileOperateMutex; + std::condition_variable fileOperateCondition; + bool isReady = false; +}; + +struct CallbackParam { + ThreadLockInfo *lockInfo; + JsRuntime &jsRuntime; + std::shared_ptr jsObj; + const char *funcName; + NativeValue * const *argv; + size_t argc; + NativeValue *result; +}; + class JsFileAccessExtAbility : public FileAccessExtAbility { public: JsFileAccessExtAbility(JsRuntime& jsRuntime); @@ -41,11 +59,21 @@ public: sptr OnConnect(const AAFwk::Want &want) override; + int OpenFile(const Uri &uri, int flags) override; + int CreateFile(const Uri &parent, const std::string &displayName, Uri &newFile) override; + int Mkdir(const Uri &parent, const std::string &displayName, Uri &newFile) override; + int Delete(const Uri &sourceFile) override; + int Move(const Uri &sourceFile, const Uri &targetParent, Uri &newFile) override; + int Rename(const Uri &sourceFile, const std::string &displayName, Uri &newFile) override; + + std::vector ListFile(const Uri &sourceFile) override; + std::vector GetRoots() override; private: + NativeValue* AsnycCallObjectMethod(const char *name, NativeValue * const *argv = nullptr, size_t argc = 0); NativeValue* CallObjectMethod(const char *name, NativeValue * const *argv = nullptr, size_t argc = 0); void GetSrcPath(std::string &srcPath); - JsRuntime& jsRuntime_; + JsRuntime &jsRuntime_; std::shared_ptr jsObj_; }; } // namespace FileAccessFwk diff --git a/frameworks/innerkits/file_access/include/napi_common_fileaccess.h b/frameworks/innerkits/file_access/include/napi_common_fileaccess.h new file mode 100644 index 0000000000000000000000000000000000000000..1051b06d6b55bcc304fcb3bc27f0d2a60bc3d73d --- /dev/null +++ b/frameworks/innerkits/file_access/include/napi_common_fileaccess.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NAPI_COMMON_FILE_ACCESS_H +#define NAPI_COMMON_FILE_ACCESS_H + +#include +#include +#include + +#include "file_access_extension_info.h" +#include "napi_common_data.h" +#include "napi_common_util.h" + +namespace OHOS { +namespace FileAccessFwk { +bool UnwrapInt64ByPropertyName(napi_env env, napi_value param, const char *propertyName, int64_t &value); + +napi_value WrapUint32ToJS(napi_env env, uint32_t value); +uint32_t UnwrapUint32FromJS(napi_env env, napi_value param, uint32_t defaultValue = 0); +bool UnwrapUint32FromJS2(napi_env env, napi_value param, uint32_t &value); +bool UnwrapUint32ByPropertyName(napi_env env, napi_value param, const char *propertyName, uint32_t &value); + +napi_value WrapBigIntUint64ToJS(napi_env env, uint64_t value); +uint64_t UnwrapBigIntUint64FromJS(napi_env env, napi_value param, uint64_t defaultValue = 0); +bool UnwrapBigIntUint64FromJS2(napi_env env, napi_value param, uint64_t &defaultValue); +bool UnwrapBigIntUint64ByPropertyName(napi_env env, napi_value param, const char *propertyName, uint64_t &value); + +napi_value WrapFileInfo(napi_env env, const FileInfo &fileInfo); +bool UnwrapFileInfo(napi_env env, napi_value param, FileInfo &fileInfo); + +napi_value WrapArrayFileInfoToJS(napi_env env, const std::vector &fileInfoVec); +bool UnwrapArrayFileInfoFromJS(napi_env env, napi_value param, std::vector &fileInfoVec); + +napi_value WrapDeviceInfo(napi_env env, const DeviceInfo &deviceInfo); +bool UnwrapDeviceInfo(napi_env env, napi_value param, DeviceInfo &deviceInfo); + +napi_value WrapArrayDeviceInfoToJS(napi_env env, const std::vector &deviceInfoVec); +bool UnwrapArrayDeviceInfoFromJS(napi_env env, napi_value param, std::vector &deviceInfoVec); +} // namespace FileAccessFwk +} // namespace OHOS +#endif // NAPI_COMMON_FILE_ACCESS_H diff --git a/frameworks/innerkits/file_access/src/file_access_ext_ability.cpp b/frameworks/innerkits/file_access/src/file_access_ext_ability.cpp index c4f0790780f7deccb35ed5a5ce21293b3e4b230e..a570e63dfeb44e19b89cac3d42911277400e88fe 100644 --- a/frameworks/innerkits/file_access/src/file_access_ext_ability.cpp +++ b/frameworks/innerkits/file_access/src/file_access_ext_ability.cpp @@ -18,6 +18,7 @@ #include "ability_loader.h" #include "connection_manager.h" #include "extension_context.h" +#include "file_access_framework_errno.h" #include "hilog_wrapper.h" #include "js_file_access_ext_ability.h" #include "runtime.h" @@ -56,5 +57,47 @@ void FileAccessExtAbility::Init(const std::shared_ptr &recor { ExtensionBase<>::Init(record, application, handler, token); } + +int FileAccessExtAbility::OpenFile(const Uri &uri, int flags) +{ + return ERR_OK; +} + +int FileAccessExtAbility::CreateFile(const Uri &parent, const std::string &displayName, Uri &newFile) +{ + return ERR_OK; +} + +int FileAccessExtAbility::Mkdir(const Uri &parent, const std::string &displayName, Uri &newFile) +{ + return ERR_OK; +} + +int FileAccessExtAbility::Delete(const Uri &sourceFile) +{ + return ERR_OK; +} + +int FileAccessExtAbility::Move(const Uri &sourceFile, const Uri &targetParent, Uri &newFile) +{ + return ERR_OK; +} + +int FileAccessExtAbility::Rename(const Uri &sourceFile, const std::string &displayName, Uri &newFile) +{ + return ERR_OK; +} + +std::vector FileAccessExtAbility::ListFile(const Uri &sourceFile) +{ + std::vector vec; + return vec; +} + +std::vector FileAccessExtAbility::GetRoots() +{ + std::vector vec; + return vec; +} } // namespace FileAccessFwk } // namespace OHOS \ No newline at end of file diff --git a/frameworks/innerkits/file_access/src/file_access_ext_connection.cpp b/frameworks/innerkits/file_access/src/file_access_ext_connection.cpp new file mode 100644 index 0000000000000000000000000000000000000000..45f0b67aafcec99ca2e75ee871e750c34ea7997e --- /dev/null +++ b/frameworks/innerkits/file_access/src/file_access_ext_connection.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "file_access_ext_connection.h" + +#include "ability_manager_client.h" +#include "file_access_ext_proxy.h" +#include "hilog_wrapper.h" + + +namespace OHOS { +namespace FileAccessFwk { +sptr FileAccessExtConnection::instance_ = nullptr; +std::mutex FileAccessExtConnection::mutex_; + +sptr FileAccessExtConnection::GetInstance() +{ + if (instance_ == nullptr) { + std::lock_guard lock(mutex_); + if (instance_ == nullptr) { + instance_ = sptr(new (std::nothrow) FileAccessExtConnection()); + } + } + return instance_; +} + +void FileAccessExtConnection::OnAbilityConnectDone( + const AppExecFwk::ElementName &element, const sptr &remoteObject, int resultCode) +{ + if (remoteObject == nullptr) { + HILOG_ERROR("%{public}s failed, remote is nullptr", __func__); + return; + } + fileExtProxy_ = iface_cast(remoteObject); + if (fileExtProxy_ == nullptr) { + HILOG_ERROR("%{public}s failed, fileExtProxy_ is nullptr", __func__); + return; + } + isConnected_.store(true); +} + +void FileAccessExtConnection::OnAbilityDisconnectDone(const AppExecFwk::ElementName &element, int resultCode) +{ + fileExtProxy_ = nullptr; + isConnected_.store(false); +} + +void FileAccessExtConnection::ConnectFileExtAbility(const AAFwk::Want &want, const sptr &token) +{ + ErrCode ret = AAFwk::AbilityManagerClient::GetInstance()->ConnectAbility(want, this, token); + HILOG_INFO("%{public}s called end, ret=%{public}d", __func__, ret); +} + +void FileAccessExtConnection::DisconnectFileExtAbility() +{ + fileExtProxy_ = nullptr; + isConnected_.store(false); + ErrCode ret = AAFwk::AbilityManagerClient::GetInstance()->DisconnectAbility(this); + HILOG_INFO("%{public}s called end, ret=%{public}d", __func__, ret); +} + +bool FileAccessExtConnection::IsExtAbilityConnected() +{ + return isConnected_.load(); +} + +sptr FileAccessExtConnection::GetFileExtProxy() +{ + return fileExtProxy_; +} +} // namespace FileAccessFwk +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/innerkits/file_access/src/file_access_ext_proxy.cpp b/frameworks/innerkits/file_access/src/file_access_ext_proxy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..55a9d5260aab6b770ab1def0f81f5ac5a45c27f1 --- /dev/null +++ b/frameworks/innerkits/file_access/src/file_access_ext_proxy.cpp @@ -0,0 +1,347 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "file_access_ext_proxy.h" +#include "file_access_framework_errno.h" +#include "hilog_wrapper.h" + +namespace OHOS { +namespace FileAccessFwk { +int FileAccessExtProxy::OpenFile(const Uri &uri, int flags) +{ + int fd = ERR_ERROR; + MessageParcel data; + if (!data.WriteInterfaceToken(FileAccessExtProxy::GetDescriptor())) { + HILOG_ERROR("%{public}s WriteInterfaceToken failed", __func__); + return fd; + } + + if (!data.WriteParcelable(&uri)) { + HILOG_ERROR("%{public}s fail to WriteParcelable uri", __func__); + return fd; + } + + if (!data.WriteInt32(flags)) { + HILOG_ERROR("%{public}s fail to WriteString mode", __func__); + return fd; + } + + MessageParcel reply; + MessageOption option; + int32_t err = Remote()->SendRequest(CMD_OPEN_FILE, data, reply, option); + if (err != NO_ERROR) { + HILOG_ERROR("%{public}s fail to SendRequest. err: %d", __func__, err); + return fd; + } + + fd = reply.ReadFileDescriptor(); + if (fd == ERR_ERROR) { + HILOG_ERROR("%{public}s fail to ReadFileDescriptor fd", __func__); + return fd; + } + return fd; +} + +int FileAccessExtProxy::CreateFile(const Uri &parent, const std::string &displayName, Uri &newFile) +{ + int ret = ERR_ERROR; + MessageParcel data; + if (!data.WriteInterfaceToken(FileAccessExtProxy::GetDescriptor())) { + HILOG_ERROR("%{public}s WriteInterfaceToken failed", __func__); + return ret; + } + + if (!data.WriteParcelable(&parent)) { + HILOG_ERROR("%{public}s fail to WriteParcelable parent", __func__); + return ret; + } + + if (!data.WriteString(displayName)) { + HILOG_ERROR("%{public}s fail to WriteString mode", __func__); + return ret; + } + + if (!data.WriteParcelable(&newFile)) { + HILOG_ERROR("%{public}s fail to WriteParcelable newFile", __func__); + return ret; + } + + MessageParcel reply; + MessageOption option; + int32_t err = Remote()->SendRequest(CMD_CREATE_FILE, data, reply, option); + if (err != NO_ERROR) { + HILOG_ERROR("%{public}s fail to SendRequest. err: %d", __func__, err); + return ret; + } + + ret = reply.ReadInt32(); + if (ret < ERR_OK) { + HILOG_ERROR("%{public}s fail to ReadInt32 ret", __func__); + return ret; + } + + std::unique_ptr tempUri(reply.ReadParcelable()); + if (!tempUri) { + HILOG_ERROR("%{public}s ReadParcelable value is nullptr.", __func__); + ret = ERR_ERROR; + return ret; + } + + newFile = Uri(*tempUri); + return ret; +} + +int FileAccessExtProxy::Mkdir(const Uri &parent, const std::string &displayName, Uri &newFile) +{ + int ret = ERR_ERROR; + MessageParcel data; + if (!data.WriteInterfaceToken(FileAccessExtProxy::GetDescriptor())) { + HILOG_ERROR("%{public}s WriteInterfaceToken failed", __func__); + return ret; + } + + if (!data.WriteParcelable(&parent)) { + HILOG_ERROR("%{public}s fail to WriteParcelable parent", __func__); + return ret; + } + + if (!data.WriteString(displayName)) { + HILOG_ERROR("%{public}s fail to WriteString displayName", __func__); + return ret; + } + + if (!data.WriteParcelable(&newFile)) { + HILOG_ERROR("%{public}s fail to WriteParcelable newFile", __func__); + return ret; + } + + MessageParcel reply; + MessageOption option; + int32_t err = Remote()->SendRequest(CMD_MKDIR, data, reply, option); + if (err != NO_ERROR) { + HILOG_ERROR("%{public}s fail to SendRequest. err: %d", __func__, err); + return ret; + } + + ret = reply.ReadInt32(); + if (ret < ERR_OK) { + HILOG_ERROR("%{public}s fail to ReadInt32 ret", __func__); + return ret; + } + + std::unique_ptr tempUri(reply.ReadParcelable()); + if (!tempUri) { + HILOG_ERROR("%{public}s ReadParcelable value is nullptr.", __func__); + ret = ERR_ERROR; + return ret; + } + + newFile = Uri(*tempUri); + return ret; +} + +int FileAccessExtProxy::Delete(const Uri &sourceFile) +{ + int ret = ERR_ERROR; + MessageParcel data; + if (!data.WriteInterfaceToken(FileAccessExtProxy::GetDescriptor())) { + HILOG_ERROR("%{public}s WriteInterfaceToken failed", __func__); + return ret; + } + + if (!data.WriteParcelable(&sourceFile)) { + HILOG_ERROR("%{public}s fail to WriteParcelable sourceFile", __func__); + return ret; + } + + MessageParcel reply; + MessageOption option; + int32_t err = Remote()->SendRequest(CMD_DELETE, data, reply, option); + if (err != NO_ERROR) { + HILOG_ERROR("%{public}s fail to SendRequest. err: %d", __func__, err); + return ret; + } + + ret = reply.ReadInt32(); + if (ret < ERR_OK) { + HILOG_ERROR("%{public}s fail to ReadInt32 ret", __func__); + return ret; + } + + return ret; +} + +int FileAccessExtProxy::Move(const Uri &sourceFile, const Uri &targetParent, Uri &newFile) +{ + int ret = ERR_ERROR; + MessageParcel data; + if (!data.WriteInterfaceToken(FileAccessExtProxy::GetDescriptor())) { + HILOG_ERROR(" %{public}s WriteInterfaceToken failed", __func__); + return ret; + } + + if (!data.WriteParcelable(&sourceFile)) { + HILOG_ERROR(" %{public}s fail to WriteParcelable sourceFile", __func__); + return ret; + } + + if (!data.WriteParcelable(&targetParent)) { + HILOG_ERROR(" %{public}s fail to WriteParcelable targetParent", __func__); + return ret; + } + + if (!data.WriteParcelable(&newFile)) { + HILOG_ERROR(" %{public}s fail to WriteParcelable newFile", __func__); + return ret; + } + + MessageParcel reply; + MessageOption option; + int32_t err = Remote()->SendRequest(CMD_MOVE, data, reply, option); + if (err != NO_ERROR) { + HILOG_ERROR(" %{public}s fail to SendRequest. err: %d", __func__, err); + return ret; + } + + ret = reply.ReadInt32(); + if (ret < ERR_OK) { + HILOG_ERROR(" %{public}s fail to ReadInt32 ret", __func__); + return ret; + } + + std::unique_ptr tempUri(reply.ReadParcelable()); + if (!tempUri) { + HILOG_ERROR(" %{public}s ReadParcelable value is nullptr.", __func__); + ret = ERR_ERROR; + return ret; + } + + newFile = Uri(*tempUri); + return ret; +} + +int FileAccessExtProxy::Rename(const Uri &sourceFile, const std::string &displayName, Uri &newFile) +{ + int ret = ERR_ERROR; + MessageParcel data; + if (!data.WriteInterfaceToken(FileAccessExtProxy::GetDescriptor())) { + HILOG_ERROR("%{public}s WriteInterfaceToken failed", __func__); + return ret; + } + + if (!data.WriteParcelable(&sourceFile)) { + HILOG_ERROR("%{public}s fail to WriteParcelable sourceFile", __func__); + return ret; + } + + if (!data.WriteString(displayName)) { + HILOG_ERROR("%{public}s fail to WriteString displayName", __func__); + return ret; + } + + if (!data.WriteParcelable(&newFile)) { + HILOG_ERROR("%{public}s fail to WriteParcelable newFile", __func__); + return ret; + } + + MessageParcel reply; + MessageOption option; + int32_t err = Remote()->SendRequest(CMD_RENAME, data, reply, option); + if (err != NO_ERROR) { + HILOG_ERROR("%{public}s fail to SendRequest. err: %d", __func__, err); + return ret; + } + + ret = reply.ReadInt32(); + if (ret < ERR_OK) { + HILOG_ERROR("%{public}s fail to ReadInt32 ret", __func__); + return ret; + } + + std::unique_ptr tempUri(reply.ReadParcelable()); + if (!tempUri) { + HILOG_ERROR("%{public}s ReadParcelable value is nullptr.", __func__); + ret = ERR_ERROR; + return ret; + } + + newFile = Uri(*tempUri); + return ret; +} + +std::vector FileAccessExtProxy::ListFile(const Uri &sourceFile) +{ + std::vector vec; + MessageParcel data; + if (!data.WriteInterfaceToken(FileAccessExtProxy::GetDescriptor())) { + HILOG_ERROR("%{public}s WriteInterfaceToken failed", __func__); + return vec; + } + + if (!data.WriteParcelable(&sourceFile)) { + HILOG_ERROR("%{public}s fail to WriteParcelable sourceFileUri", __func__); + return vec; + } + + MessageParcel reply; + MessageOption option; + int32_t err = Remote()->SendRequest(CMD_LIST_FILE, data, reply, option); + if (err != NO_ERROR) { + HILOG_ERROR("%{public}s fail to SendRequest. err: %d", __func__, err); + return vec; + } + + vec.clear(); + int64_t count = reply.ReadInt64(); + for (int32_t i = 0; i < count; i++) { + std::unique_ptr fileInfo(reply.ReadParcelable()); + if (fileInfo != nullptr) { + vec.push_back(*fileInfo); + } + } + + return vec; +} + +std::vector FileAccessExtProxy::GetRoots() +{ + std::vector vec; + MessageParcel data; + if (!data.WriteInterfaceToken(FileAccessExtProxy::GetDescriptor())) { + HILOG_ERROR("%{public}s WriteInterfaceToken failed", __func__); + return vec; + } + + MessageParcel reply; + MessageOption option; + int32_t err = Remote()->SendRequest(CMD_GET_ROOTS, data, reply, option); + if (err != NO_ERROR) { + HILOG_ERROR("%{public}s fail to SendRequest. err: %d", __func__, err); + return vec; + } + + vec.clear(); + uint64_t count = reply.ReadUint64(); + for (uint64_t i = 0; i < count; i++) { + std::unique_ptr deviceInfo(reply.ReadParcelable()); + if (deviceInfo != nullptr) { + vec.push_back(*deviceInfo); + } + } + + return vec; +} +} // namespace FileAccessFwk +} // namespace OHOS diff --git a/frameworks/innerkits/file_access/src/file_access_ext_stub.cpp b/frameworks/innerkits/file_access/src/file_access_ext_stub.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dc651d19a3c884625e04d61395044e36675d9979 --- /dev/null +++ b/frameworks/innerkits/file_access/src/file_access_ext_stub.cpp @@ -0,0 +1,289 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "file_access_ext_stub.h" + +#include "hilog_wrapper.h" + +namespace OHOS { +namespace FileAccessFwk { +FileAccessExtStub::FileAccessExtStub() +{ + stubFuncMap_[CMD_OPEN_FILE] = &FileAccessExtStub::CmdOpenFile; + stubFuncMap_[CMD_CREATE_FILE] = &FileAccessExtStub::CmdCreateFile; + stubFuncMap_[CMD_MKDIR] = &FileAccessExtStub::CmdMkdir; + stubFuncMap_[CMD_DELETE] = &FileAccessExtStub::CmdDelete; + stubFuncMap_[CMD_MOVE] = &FileAccessExtStub::CmdMove; + stubFuncMap_[CMD_RENAME] = &FileAccessExtStub::CmdRename; + stubFuncMap_[CMD_LIST_FILE] = &FileAccessExtStub::CmdListFile; + stubFuncMap_[CMD_GET_ROOTS] = &FileAccessExtStub::CmdGetRoots; +} + +FileAccessExtStub::~FileAccessExtStub() +{ + stubFuncMap_.clear(); +} + +int FileAccessExtStub::OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel& reply, + MessageOption& option) +{ + std::u16string descriptor = FileAccessExtStub::GetDescriptor(); + std::u16string remoteDescriptor = data.ReadInterfaceToken(); + if (descriptor != remoteDescriptor) { + return ERR_INVALID_STATE; + } + + const auto &itFunc = stubFuncMap_.find(code); + if (itFunc != stubFuncMap_.end()) { + return (this->*(itFunc->second))(data, reply); + } + + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); +} + +ErrCode FileAccessExtStub::CmdOpenFile(MessageParcel &data, MessageParcel &reply) +{ + std::shared_ptr uri(data.ReadParcelable()); + if (uri == nullptr) { + HILOG_ERROR("%{public}s uri is nullptr", __func__); + return ERR_INVALID_VALUE; + } + int flags = data.ReadInt32(); + if (flags < 0) { + HILOG_ERROR("%{public}s mode is invalid", __func__); + return ERR_INVALID_VALUE; + } + int fd = OpenFile(*uri, flags); + if (fd < 0) { + HILOG_ERROR("%{public}s OpenFile fail, fd is %{pubilc}d", __func__, fd); + return ERR_INVALID_VALUE; + } + + if (!reply.WriteFileDescriptor(fd)) { + HILOG_ERROR("%{public}s fail to WriteFileDescriptor fd", __func__); + return ERR_INVALID_VALUE; + } + return NO_ERROR; +} + +ErrCode FileAccessExtStub::CmdCreateFile(MessageParcel &data, MessageParcel &reply) +{ + std::shared_ptr parent(data.ReadParcelable()); + if (parent == nullptr) { + HILOG_ERROR("%{public}s parent is nullptr", __func__); + return ERR_INVALID_VALUE; + } + std::string displayName = data.ReadString(); + if (displayName.empty()) { + HILOG_ERROR("%{public}s mode is nullptr", __func__); + return ERR_INVALID_VALUE; + } + std::shared_ptr fileNew(data.ReadParcelable()); + if (fileNew == nullptr) { + HILOG_ERROR("%{public}s fileNew is nullptr", __func__); + return ERR_INVALID_VALUE; + } + + int ret = CreateFile(*parent, displayName, *fileNew); + if (ret < 0) { + HILOG_ERROR("%{public}s CreateFile fail, ret is %{pubilc}d", __func__, ret); + return ERR_INVALID_VALUE; + } + + if (!reply.WriteInt32(ret)) { + HILOG_ERROR("%{public}s fail to WriteInt32 ret", __func__); + return ERR_INVALID_VALUE; + } + + if (!reply.WriteParcelable(&(*fileNew))) { + HILOG_ERROR("%{public}s fail to WriteParcelable type", __func__); + return ERR_INVALID_VALUE; + } + return NO_ERROR; +} + +ErrCode FileAccessExtStub::CmdMkdir(MessageParcel &data, MessageParcel &reply) +{ + std::shared_ptr parent(data.ReadParcelable()); + if (parent == nullptr) { + HILOG_ERROR("%{public}s parent is nullptr", __func__); + return ERR_INVALID_VALUE; + } + std::string displayName = data.ReadString(); + if (displayName.empty()) { + HILOG_ERROR("%{public}s mode is nullptr", __func__); + return ERR_INVALID_VALUE; + } + std::shared_ptr fileNew(data.ReadParcelable()); + if (fileNew == nullptr) { + HILOG_ERROR("%{public}s fileNew is nullptr", __func__); + return ERR_INVALID_VALUE; + } + + int ret = Mkdir(*parent, displayName, *fileNew); + if (ret < 0) { + HILOG_ERROR("%{public}s Mkdir fail, ret is %{pubilc}d", __func__, ret); + return ERR_INVALID_VALUE; + } + + if (!reply.WriteInt32(ret)) { + HILOG_ERROR("%{public}s fail to WriteInt32 ret", __func__); + return ERR_INVALID_VALUE; + } + + if (!reply.WriteParcelable(&(*fileNew))) { + HILOG_ERROR("%{public}s fail to WriteParcelable type", __func__); + return ERR_INVALID_VALUE; + } + return NO_ERROR; +} + +ErrCode FileAccessExtStub::CmdDelete(MessageParcel &data, MessageParcel &reply) +{ + std::shared_ptr uri(data.ReadParcelable()); + if (uri == nullptr) { + HILOG_ERROR("%{public}s uri is nullptr", __func__); + return ERR_INVALID_VALUE; + } + + int ret = Delete(*uri); + if (ret < 0) { + HILOG_ERROR("%{public}s Delete fail, ret is %{pubilc}d", __func__, ret); + return ERR_INVALID_VALUE; + } + + if (!reply.WriteInt32(ret)) { + HILOG_ERROR("%{public}s fail to WriteFileDescriptor ret", __func__); + return ERR_INVALID_VALUE; + } + return NO_ERROR; +} + +ErrCode FileAccessExtStub::CmdMove(MessageParcel &data, MessageParcel &reply) +{ + std::shared_ptr sourceFile(data.ReadParcelable()); + if (sourceFile == nullptr) { + HILOG_ERROR(" %{public}s sourceFile is nullptr", __func__); + return ERR_INVALID_VALUE; + } + std::shared_ptr targetParent(data.ReadParcelable()); + if (targetParent == nullptr) { + HILOG_ERROR(" %{public}s targetParent is nullptr", __func__); + return ERR_INVALID_VALUE; + } + std::shared_ptr fileNew(data.ReadParcelable()); + if (fileNew == nullptr) { + HILOG_ERROR(" %{public}s fileNew is nullptr", __func__); + return ERR_INVALID_VALUE; + } + + int ret = Move(*sourceFile, *targetParent, *fileNew); + if (ret < 0) { + HILOG_ERROR(" %{public}s fail, ret is %{pubilc}d", __func__, ret); + return ERR_INVALID_VALUE; + } + + if (!reply.WriteInt32(ret)) { + HILOG_ERROR(" %{public}s fail to WriteInt32 ret", __func__); + return ERR_INVALID_VALUE; + } + + if (!reply.WriteParcelable(&(*fileNew))) { + HILOG_ERROR(" %{public}s fail to WriteParcelable type", __func__); + return ERR_INVALID_VALUE; + } + return NO_ERROR; +} + +ErrCode FileAccessExtStub::CmdRename(MessageParcel &data, MessageParcel &reply) +{ + std::shared_ptr sourceFile(data.ReadParcelable()); + if (sourceFile == nullptr) { + HILOG_ERROR("%{public}s sourceFileUri is nullptr", __func__); + return ERR_INVALID_VALUE; + } + std::string displayName = data.ReadString(); + if (displayName.empty()) { + HILOG_ERROR("%{public}s mode is nullptr", __func__); + return ERR_INVALID_VALUE; + } + std::shared_ptr fileNew(data.ReadParcelable()); + if (fileNew == nullptr) { + HILOG_ERROR("%{public}s fileUriNew is nullptr", __func__); + return ERR_INVALID_VALUE; + } + + int ret = Rename(*sourceFile, displayName, *fileNew); + if (ret < 0) { + HILOG_ERROR("%{public}s Rename fail, ret is %{pubilc}d", __func__, ret); + return ERR_INVALID_VALUE; + } + + if (!reply.WriteInt32(ret)) { + HILOG_ERROR("%{public}s fail to WriteInt32 ret", __func__); + return ERR_INVALID_VALUE; + } + + if (!reply.WriteParcelable(&(*fileNew))) { + HILOG_ERROR("%{public}s fail to WriteParcelable type", __func__); + return ERR_INVALID_VALUE; + } + + return NO_ERROR; +} + +ErrCode FileAccessExtStub::CmdListFile(MessageParcel &data, MessageParcel &reply) +{ + std::shared_ptr uri(data.ReadParcelable()); + if (uri == nullptr) { + HILOG_ERROR("%{public}s uri is nullptr", __func__); + return ERR_INVALID_VALUE; + } + + std::vector vec = ListFile(*uri); + uint64_t count {vec.size()}; + if (!reply.WriteUint64(count)) { + HILOG_ERROR("%{public}s fail to WriteInt32 count", __func__); + return ERR_INVALID_VALUE; + } + for (uint64_t i = 0; i < count; i++) { + if (!reply.WriteParcelable(&vec[i])) { + HILOG_ERROR("%{public}s fail to WriteParcelable vec", __func__); + return ERR_INVALID_VALUE; + } + } + + return NO_ERROR; +} + +ErrCode FileAccessExtStub::CmdGetRoots(MessageParcel &data, MessageParcel &reply) +{ + std::vector vec = GetRoots(); + uint64_t count {vec.size()}; + if (!reply.WriteUint64(count)) { + HILOG_ERROR("%{public}s fail to WriteInt32 count", __func__); + return ERR_INVALID_VALUE; + } + for (uint64_t i = 0; i < count; i++) { + if (!reply.WriteParcelable(&vec[i])) { + HILOG_ERROR("%{public}s fail to WriteParcelable ret", __func__); + return ERR_INVALID_VALUE; + } + } + + return NO_ERROR; +} +} // namespace FileAccessFwk +} // namespace OHOS diff --git a/frameworks/innerkits/file_access/src/file_access_ext_stub_impl.cpp b/frameworks/innerkits/file_access/src/file_access_ext_stub_impl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9ffac663a13914ab38180b7212ee8a14f5fb81ab --- /dev/null +++ b/frameworks/innerkits/file_access/src/file_access_ext_stub_impl.cpp @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "file_access_ext_stub_impl.h" + +#include "hilog_wrapper.h" + +namespace OHOS { +namespace FileAccessFwk { +std::shared_ptr FileAccessExtStubImpl::GetOwner() +{ + return extension_; +} + +int FileAccessExtStubImpl::OpenFile(const Uri &uri, int flags) +{ + int ret = -1; + auto extension = GetOwner(); + if (extension == nullptr) { + HILOG_ERROR("%{public}s end failed.", __func__); + return ret; + } + ret = extension->OpenFile(uri, flags); + return ret; +} + +int FileAccessExtStubImpl::CreateFile(const Uri &parent, const std::string &displayName, Uri &newFile) +{ + int ret = -1; + auto extension = GetOwner(); + if (extension == nullptr) { + HILOG_ERROR("%{public}s end failed.", __func__); + return ret; + } + ret = extension->CreateFile(parent, displayName, newFile); + return ret; +} + +int FileAccessExtStubImpl::Mkdir(const Uri &parent, const std::string &displayName, Uri &newFile) +{ + int ret = -1; + auto extension = GetOwner(); + if (extension == nullptr) { + HILOG_ERROR("%{public}s end failed.", __func__); + return ret; + } + ret = extension->Mkdir(parent, displayName, newFile); + return ret; +} + +int FileAccessExtStubImpl::Delete(const Uri &sourceFile) +{ + int ret = -1; + auto extension = GetOwner(); + if (extension == nullptr) { + HILOG_ERROR("%{public}s end failed.", __func__); + return ret; + } + ret = extension->Delete(sourceFile); + return ret; +} + +int FileAccessExtStubImpl::Move(const Uri &sourceFile, const Uri &targetParent, Uri &newFile) +{ + int ret = -1; + auto extension = GetOwner(); + if (extension == nullptr) { + HILOG_ERROR("%{public}s end failed.", __func__); + return ret; + } + ret = extension->Move(sourceFile, targetParent, newFile); + return ret; +} + +int FileAccessExtStubImpl::Rename(const Uri &sourceFile, const std::string &displayName, Uri &newFile) +{ + int ret = -1; + auto extension = GetOwner(); + if (extension == nullptr) { + HILOG_ERROR("%{public}s end failed.", __func__); + return ret; + } + ret = extension->Rename(sourceFile, displayName, newFile); + return ret; +} + +std::vector FileAccessExtStubImpl::ListFile(const Uri &sourceFile) +{ + std::vector vec; + auto extension = GetOwner(); + if (extension == nullptr) { + HILOG_ERROR("%{public}s end failed.", __func__); + return vec; + } + vec = extension->ListFile(sourceFile); + return vec; +} + +std::vector FileAccessExtStubImpl::GetRoots() +{ + std::vector vec; + auto extension = GetOwner(); + if (extension == nullptr) { + HILOG_ERROR("%{public}s end failed.", __func__); + return vec; + } + vec = extension->GetRoots(); + return vec; +} +} // namespace FileAccessFwk +} // namespace OHOS diff --git a/frameworks/innerkits/file_access/src/file_access_helper.cpp b/frameworks/innerkits/file_access/src/file_access_helper.cpp new file mode 100644 index 0000000000000000000000000000000000000000..593c69894caf487ce74bf2791da3e434f5db4c1a --- /dev/null +++ b/frameworks/innerkits/file_access/src/file_access_helper.cpp @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "file_access_helper.h" + +#include "file_access_framework_errno.h" +#include "hilog_wrapper.h" +#include "ifile_access_ext_base.h" + +namespace OHOS { +namespace FileAccessFwk { +FileAccessHelper::FileAccessHelper(const std::shared_ptr &context, + const AAFwk::Want &want, const sptr &fileAccessExtProxy) +{ + token_ = context->GetToken(); + want_ = want; + fileAccessExtProxy_ = fileAccessExtProxy; + fileAccessExtConnection_ = FileAccessExtConnection::GetInstance(); +} + +void FileAccessHelper::AddFileAccessDeathRecipient(const sptr &token) +{ + if (token != nullptr && callerDeathRecipient_ != nullptr) { + token->RemoveDeathRecipient(callerDeathRecipient_); + } + if (callerDeathRecipient_ == nullptr) { + callerDeathRecipient_ = + new FileAccessDeathRecipient(std::bind(&FileAccessHelper::OnSchedulerDied, this, std::placeholders::_1)); + } + if (token != nullptr) { + token->AddDeathRecipient(callerDeathRecipient_); + } +} + +void FileAccessHelper::OnSchedulerDied(const wptr &remote) +{ + auto object = remote.promote(); + object = nullptr; + fileAccessExtProxy_ = nullptr; +} + +FileAccessHelper::FileAccessHelper(const sptr &token, + const AAFwk::Want &want, const sptr &fileAccessExtProxy) +{ + token_ = token; + want_ = want; + fileAccessExtProxy_ = fileAccessExtProxy; + fileAccessExtConnection_ = FileAccessExtConnection::GetInstance(); +} + +std::shared_ptr FileAccessHelper::Creator( + const sptr &token, const AAFwk::Want &want) +{ + sptr fileAccessExtProxy = nullptr; + + sptr fileAccessExtConnection = FileAccessExtConnection::GetInstance(); + if (!fileAccessExtConnection->IsExtAbilityConnected()) { + fileAccessExtConnection->ConnectFileExtAbility(want, token); + } + fileAccessExtProxy = fileAccessExtConnection->GetFileExtProxy(); + if (fileAccessExtProxy == nullptr) { + HILOG_WARN("FileAccessHelper::Creator get invalid fileAccessExtProxy"); + } + + FileAccessHelper *ptrDataShareHelper = new (std::nothrow) FileAccessHelper(token, want, fileAccessExtProxy); + if (ptrDataShareHelper == nullptr) { + HILOG_ERROR("FileAccessHelper::Creator failed, create FileAccessHelper failed"); + return nullptr; + } + + return std::shared_ptr(ptrDataShareHelper); +} + +std::shared_ptr FileAccessHelper::Creator( + const std::shared_ptr &context, const AAFwk::Want &want) +{ + if (context == nullptr) { + HILOG_ERROR("%{public}s failed, context == nullptr", __func__); + return nullptr; + } + + sptr fileAccessExtProxy = nullptr; + sptr fileAccessExtConnection = FileAccessExtConnection::GetInstance(); + if (!fileAccessExtConnection->IsExtAbilityConnected()) { + fileAccessExtConnection->ConnectFileExtAbility(want, context->GetToken()); + } + fileAccessExtProxy = fileAccessExtConnection->GetFileExtProxy(); + if (fileAccessExtProxy == nullptr) { + HILOG_WARN("%{public}s get invalid fileAccessExtProxy", __func__); + } + + FileAccessHelper *ptrFileAccessHelper = new (std::nothrow) FileAccessHelper(context, want, fileAccessExtProxy); + if (ptrFileAccessHelper == nullptr) { + HILOG_ERROR("%{public}s failed, create FileAccessHelper failed", __func__); + return nullptr; + } + + return std::shared_ptr(ptrFileAccessHelper); +} + +bool FileAccessHelper::Release() +{ + if (fileAccessExtConnection_->IsExtAbilityConnected()) { + fileAccessExtConnection_->DisconnectFileExtAbility(); + } + fileAccessExtProxy_ = nullptr; + return true; +} + +bool FileAccessHelper::GetProxy() +{ + if (!fileAccessExtConnection_->IsExtAbilityConnected()) { + fileAccessExtConnection_->ConnectFileExtAbility(want_, token_); + } + fileAccessExtProxy_ = fileAccessExtConnection_->GetFileExtProxy(); + if (isSystemCaller_ && fileAccessExtProxy_) { + AddFileAccessDeathRecipient(fileAccessExtProxy_->AsObject()); + } + + if (fileAccessExtProxy_ == nullptr) { + HILOG_ERROR("%{public}s failed with invalid fileAccessExtProxy_", __func__); + return false; + } + return true; +} + +int FileAccessHelper::OpenFile(Uri &uri, int flags) +{ + int fd = ERR_ERROR; + if (!GetProxy()) { + HILOG_ERROR("%{public}s failed with invalid fileAccessExtProxy_", __func__); + return fd; + } + + fd = fileAccessExtProxy_->OpenFile(uri, flags); + return fd; +} + +int FileAccessHelper::CreateFile(Uri &parent, const std::string &displayName, Uri &newFile) +{ + int index = ERR_ERROR; + if (!GetProxy()) { + HILOG_ERROR("%{public}s failed with invalid fileAccessExtProxy_", __func__); + return index; + } + + index = fileAccessExtProxy_->CreateFile(parent, displayName, newFile); + return index; +} + +int FileAccessHelper::Mkdir(Uri &parent, const std::string &displayName, Uri &newDir) +{ + int index = ERR_ERROR; + if (fileAccessExtProxy_ == nullptr) { + HILOG_ERROR("%{public}s failed with invalid fileAccessExtProxy_", __func__); + return index; + } + + index = fileAccessExtProxy_->Mkdir(parent, displayName, newDir); + return index; +} + +int FileAccessHelper::Delete(Uri &selectFile) +{ + int index = ERR_ERROR; + if (!GetProxy()) { + HILOG_ERROR("%{public}s failed with invalid fileAccessExtProxy_", __func__); + return index; + } + + index = fileAccessExtProxy_->Delete(selectFile); + return index; +} + +int FileAccessHelper::Move(Uri &sourceFile, Uri &targetParent, Uri &newFile) +{ + int index = ERR_ERROR; + if (!GetProxy()) { + HILOG_ERROR("%{public}s failed with invalid fileAccessExtProxy_", __func__); + return index; + } + + index = fileAccessExtProxy_->Move(sourceFile, targetParent, newFile); + return index; +} + +int FileAccessHelper::Rename(Uri &sourceFile, const std::string &displayName, Uri &newFile) +{ + int index = ERR_ERROR; + if (!GetProxy()) { + HILOG_ERROR("%{public}s failed with invalid fileAccessExtProxy_", __func__); + return index; + } + + index = fileAccessExtProxy_->Rename(sourceFile, displayName, newFile); + return index; +} + +std::vector FileAccessHelper::ListFile(Uri &sourceFile) +{ + std::vector results; + if (!GetProxy()) { + HILOG_ERROR("%{public}s failed with invalid fileAccessExtProxy_", __func__); + return results; + } + + results = fileAccessExtProxy_->ListFile(sourceFile); + return results; +} + +std::vector FileAccessHelper::GetRoots() +{ + std::vector results; + + if (!GetProxy()) { + HILOG_ERROR("%{public}s failed with invalid fileAccessExtProxy_", __func__); + return results; + } + + results = fileAccessExtProxy_->GetRoots(); + return results; +} + +void FileAccessDeathRecipient::OnRemoteDied(const wptr &remote) +{ + if (handler_) { + handler_(remote); + } +} + +FileAccessDeathRecipient::FileAccessDeathRecipient(RemoteDiedHandler handler) : handler_(handler) +{ +} + +FileAccessDeathRecipient::~FileAccessDeathRecipient() +{ +} +} // namespace FileAccessFwk +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/innerkits/file_access/src/js_file_access_ext_ability.cpp b/frameworks/innerkits/file_access/src/js_file_access_ext_ability.cpp index d11607cc84df20e9d58ec533aa5d6191efb3f468..2d69bfe0910235242424eed98dd21df58c6dc012 100644 --- a/frameworks/innerkits/file_access/src/js_file_access_ext_ability.cpp +++ b/frameworks/innerkits/file_access/src/js_file_access_ext_ability.cpp @@ -15,15 +15,18 @@ #include "js_file_access_ext_ability.h" -#include "extension_context.h" #include "ability_info.h" #include "accesstoken_kit.h" +#include "extension_context.h" +#include "file_access_ext_stub_impl.h" +#include "file_access_framework_errno.h" #include "hilog_wrapper.h" #include "ipc_skeleton.h" #include "js_runtime.h" #include "js_runtime_utils.h" #include "napi/native_api.h" #include "napi/native_node_api.h" +#include "napi_common_fileaccess.h" #include "napi_common_util.h" #include "napi_common_want.h" #include "napi_remote_object.h" @@ -31,7 +34,9 @@ namespace OHOS { namespace FileAccessFwk { namespace { +constexpr size_t ARGC_ZERO = 0; constexpr size_t ARGC_ONE = 1; +constexpr size_t ARGC_TWO = 2; } using namespace OHOS::AppExecFwk; @@ -88,7 +93,14 @@ void JsFileAccessExtAbility::OnStart(const AAFwk::Want &want) sptr JsFileAccessExtAbility::OnConnect(const AAFwk::Want &want) { Extension::OnConnect(want); - return nullptr; + sptr remoteObject = new (std::nothrow) FileAccessExtStubImpl( + std::static_pointer_cast(shared_from_this()), + reinterpret_cast(&jsRuntime_.GetNativeEngine())); + if (remoteObject == nullptr) { + HILOG_ERROR("%{public}s No memory allocated for FileExtStubImpl", __func__); + return nullptr; + } + return remoteObject->AsObject(); } NativeValue* JsFileAccessExtAbility::CallObjectMethod(const char* name, NativeValue* const* argv, size_t argc) @@ -121,6 +133,71 @@ NativeValue* JsFileAccessExtAbility::CallObjectMethod(const char* name, NativeVa return handleScope.Escape(nativeEngine.CallFunction(value, method, argv, argc)); } +static bool DoAsnycWork(CallbackParam *param) +{ + if (param == nullptr || param->jsObj == nullptr) { + HILOG_ERROR("Not found js file object"); + return false; + } + HandleScope handleScope(param->jsRuntime); + NativeValue* value = param->jsObj->Get(); + if (value == nullptr) { + HILOG_ERROR("Failed to get native value object"); + return false; + } + NativeObject* obj = ConvertNativeValueTo(value); + if (obj == nullptr) { + HILOG_ERROR("Failed to get FileExtAbility object"); + return false; + } + NativeValue* method = obj->GetProperty(param->funcName); + if (method == nullptr) { + HILOG_ERROR("Failed to get '%{public}s' from FileExtAbility object", param->funcName); + return false; + } + auto& nativeEngine = param->jsRuntime.GetNativeEngine(); + param->result = handleScope.Escape(nativeEngine.CallFunction(value, method, param->argv, param->argc)); + return true; +} + +NativeValue* JsFileAccessExtAbility::AsnycCallObjectMethod(const char* name, NativeValue* const* argv, size_t argc) +{ + std::shared_ptr lockInfo = std::make_shared(); + std::shared_ptr param = std::make_shared(CallbackParam { + .lockInfo = lockInfo.get(), + .jsRuntime = jsRuntime_, + .jsObj = jsObj_, + .funcName = name, + .argv = argv, + .argc = argc, + .result = nullptr + }); + if (param == nullptr) { + HILOG_ERROR("failed to new param"); + return nullptr; + } + uv_loop_s *loop = nullptr; + napi_get_uv_event_loop(reinterpret_cast(&jsRuntime_.GetNativeEngine()), &loop); + std::shared_ptr work = std::make_shared(); + if (work == nullptr) { + HILOG_ERROR("failed to new uv_work_t"); + return nullptr; + } + work->data = reinterpret_cast(param.get()); + uv_queue_work(loop, work.get(), [](uv_work_t *work) {}, [](uv_work_t *work, int status) { + CallbackParam *param = reinterpret_cast(work->data); + if (!DoAsnycWork(param)) { + HILOG_ERROR("failed to call DoAsnycWork"); + } + std::unique_lock lock(param->lockInfo->fileOperateMutex); + param->lockInfo->isReady = true; + param->lockInfo->fileOperateCondition.notify_all(); + }); + std::unique_lock lock(param->lockInfo->fileOperateMutex); + param->lockInfo->fileOperateCondition.wait(lock, [param]() { return param->lockInfo->isReady; }); + return std::move(param->result); +} + void JsFileAccessExtAbility::GetSrcPath(std::string &srcPath) { if (!Extension::abilityInfo_->isStageBasedModel) { @@ -141,5 +218,212 @@ void JsFileAccessExtAbility::GetSrcPath(std::string &srcPath) srcPath.append(".abc"); } } + +int JsFileAccessExtAbility::OpenFile(const Uri &uri, int flags) +{ + HandleScope handleScope(jsRuntime_); + napi_env env = reinterpret_cast(&jsRuntime_.GetNativeEngine()); + + napi_value napiUri = nullptr; + napi_create_string_utf8(env, uri.ToString().c_str(), NAPI_AUTO_LENGTH, &napiUri); + napi_value napiFlags = nullptr; + napi_create_int32(env, flags, &napiFlags); + + NativeValue* nativeUri = reinterpret_cast(napiUri); + NativeValue* nativeFlags = reinterpret_cast(napiFlags); + NativeValue* argv[] = {nativeUri, nativeFlags}; + NativeValue* nativeResult = AsnycCallObjectMethod("openFile", argv, ARGC_TWO); + int ret = ERR_ERROR; + if (nativeResult == nullptr) { + HILOG_ERROR("%{public}s call openFile with return null.", __func__); + return ret; + } + ret = OHOS::AppExecFwk::UnwrapInt32FromJS(env, reinterpret_cast(nativeResult)); + return ret; +} + +int JsFileAccessExtAbility::CreateFile(const Uri &parent, const std::string &displayName, Uri &newFile) +{ + HandleScope handleScope(jsRuntime_); + napi_env env = reinterpret_cast(&jsRuntime_.GetNativeEngine()); + + napi_value napiParent = nullptr; + napi_create_string_utf8(env, parent.ToString().c_str(), NAPI_AUTO_LENGTH, &napiParent); + napi_value napiDisplayName = nullptr; + napi_create_string_utf8(env, displayName.c_str(), NAPI_AUTO_LENGTH, &napiDisplayName); + + NativeValue* nativeParent = reinterpret_cast(napiParent); + NativeValue* nativeDisplayName = reinterpret_cast(napiDisplayName); + NativeValue* argv[] = {nativeParent, nativeDisplayName}; + NativeValue* nativeResult = AsnycCallObjectMethod("createFile", argv, ARGC_TWO); + int ret = ERR_ERROR; + if (nativeResult == nullptr) { + HILOG_ERROR("%{public}s call createFile with return null.", __func__); + return ret; + } + std::string uriStr = OHOS::AppExecFwk::UnwrapStringFromJS(env, reinterpret_cast(nativeResult)); + if (uriStr.empty()) { + HILOG_ERROR("%{public}s call Mkdir with return empty.", __func__); + return ret; + } else { + ret = NO_ERROR; + } + newFile = Uri(uriStr); + return ret; +} + +int JsFileAccessExtAbility::Mkdir(const Uri &parent, const std::string &displayName, Uri &newFile) +{ + HandleScope handleScope(jsRuntime_); + napi_env env = reinterpret_cast(&jsRuntime_.GetNativeEngine()); + + napi_value napiParent = nullptr; + napi_create_string_utf8(env, parent.ToString().c_str(), NAPI_AUTO_LENGTH, &napiParent); + napi_value napiDisplayName = nullptr; + napi_create_string_utf8(env, displayName.c_str(), NAPI_AUTO_LENGTH, &napiDisplayName); + + NativeValue* nativeParent = reinterpret_cast(napiParent); + NativeValue* nativeDisplayName = reinterpret_cast(napiDisplayName); + NativeValue* argv[] = {nativeParent, nativeDisplayName}; + NativeValue* nativeResult = AsnycCallObjectMethod("mkdir", argv, ARGC_TWO); + int ret = ERR_ERROR; + if (nativeResult == nullptr) { + HILOG_ERROR("%{public}s call Mkdir with return null.", __func__); + return ret; + } + std::string uriStr = OHOS::AppExecFwk::UnwrapStringFromJS(env, reinterpret_cast(nativeResult)); + if (uriStr.empty()) { + HILOG_ERROR("%{public}s call Mkdir with return empty.", __func__); + return ret; + } else { + ret = NO_ERROR; + } + newFile = Uri(uriStr); + return ret; +} + +int JsFileAccessExtAbility::Delete(const Uri &sourceFile) +{ + HandleScope handleScope(jsRuntime_); + napi_env env = reinterpret_cast(&jsRuntime_.GetNativeEngine()); + + napi_value napiUri = nullptr; + napi_create_string_utf8(env, sourceFile.ToString().c_str(), NAPI_AUTO_LENGTH, &napiUri); + + NativeValue* nativeUri = reinterpret_cast(napiUri); + NativeValue* argv[] = {nativeUri}; + NativeValue* nativeResult = AsnycCallObjectMethod("delete", argv, ARGC_ONE); + int ret = ERR_ERROR; + if (nativeResult == nullptr) { + HILOG_ERROR("%{public}s call delete with return null.", __func__); + return ret; + } + ret = OHOS::AppExecFwk::UnwrapInt32FromJS(env, reinterpret_cast(nativeResult)); + return ret; +} + +int JsFileAccessExtAbility::Move(const Uri &sourceFile, const Uri &targetParent, Uri &newFile) +{ + HandleScope handleScope(jsRuntime_); + napi_env env = reinterpret_cast(&jsRuntime_.GetNativeEngine()); + + napi_value napiSourceFile = nullptr; + napi_create_string_utf8(env, sourceFile.ToString().c_str(), NAPI_AUTO_LENGTH, &napiSourceFile); + napi_value napiTargetParent = nullptr; + napi_create_string_utf8(env, targetParent.ToString().c_str(), NAPI_AUTO_LENGTH, &napiTargetParent); + + NativeValue* nativeSourceFile = reinterpret_cast(napiSourceFile); + NativeValue* nativeTargetParent = reinterpret_cast(napiTargetParent); + NativeValue* argv[] = {nativeSourceFile, nativeTargetParent}; + NativeValue* nativeResult = AsnycCallObjectMethod("move", argv, ARGC_TWO); + int ret = ERR_ERROR; + if (nativeResult == nullptr) { + HILOG_ERROR("%{public}s call move with return null.", __func__); + return ret; + } + std::string uriStr = OHOS::AppExecFwk::UnwrapStringFromJS(env, reinterpret_cast(nativeResult)); + if (uriStr.empty()) { + HILOG_ERROR("%{public}s call move with return empty.", __func__); + return ret; + } else { + ret = NO_ERROR; + } + newFile = Uri(uriStr); + return ret; +} + +int JsFileAccessExtAbility::Rename(const Uri &sourceFile, const std::string &displayName, Uri &newFile) +{ + HandleScope handleScope(jsRuntime_); + napi_env env = reinterpret_cast(&jsRuntime_.GetNativeEngine()); + + napi_value napiSourceFile = nullptr; + napi_create_string_utf8(env, sourceFile.ToString().c_str(), NAPI_AUTO_LENGTH, &napiSourceFile); + napi_value napiDisplayName = nullptr; + napi_create_string_utf8(env, displayName.c_str(), NAPI_AUTO_LENGTH, &napiDisplayName); + + NativeValue* nativeSourceFile = reinterpret_cast(napiSourceFile); + NativeValue* nativeDisplayName = reinterpret_cast(napiDisplayName); + NativeValue* argv[] = {nativeSourceFile, nativeDisplayName}; + NativeValue* nativeResult = AsnycCallObjectMethod("rename", argv, ARGC_TWO); + int ret = ERR_ERROR; + if (nativeResult == nullptr) { + HILOG_ERROR("%{public}s call rename with return null.", __func__); + return ret; + } + std::string uriStr = OHOS::AppExecFwk::UnwrapStringFromJS(env, reinterpret_cast(nativeResult)); + if (uriStr.empty()) { + HILOG_ERROR("%{public}s call rename with return empty.", __func__); + return ret; + } else { + ret = NO_ERROR; + } + newFile = Uri(uriStr); + return ret; +} + +std::vector JsFileAccessExtAbility::ListFile(const Uri &sourceFile) +{ + HandleScope handleScope(jsRuntime_); + napi_env env = reinterpret_cast(&jsRuntime_.GetNativeEngine()); + + napi_value napiUri = nullptr; + std::vector vec; + napi_create_string_utf8(env, sourceFile.ToString().c_str(), NAPI_AUTO_LENGTH, &napiUri); + + NativeValue* nativeUri = reinterpret_cast(napiUri); + NativeValue* argv[] = {nativeUri}; + NativeValue* nativeResult = AsnycCallObjectMethod("listFile", argv, ARGC_ONE); + if (nativeResult == nullptr) { + HILOG_ERROR("%{public}s call listFile with return null.", __func__); + return vec; + } + if (UnwrapArrayFileInfoFromJS(env, reinterpret_cast(nativeResult), vec)) { + return vec; + } else { + HILOG_ERROR("%{public}s end with faild.", __func__); + return vec; + } +} + +std::vector JsFileAccessExtAbility::GetRoots() +{ + HandleScope handleScope(jsRuntime_); + napi_env env = reinterpret_cast(&jsRuntime_.GetNativeEngine()); + + std::vector vec; + NativeValue* argv[] = {}; + NativeValue* nativeResult = AsnycCallObjectMethod("getRoots", argv, ARGC_ZERO); + if (nativeResult == nullptr) { + HILOG_ERROR("%{public}s call getRoots with return null.", __func__); + return vec; + } + if (UnwrapArrayDeviceInfoFromJS(env, reinterpret_cast(nativeResult), vec)) { + return vec; + } else { + HILOG_ERROR("%{public}s end with faild.", __func__); + return vec; + } +} } // namespace FileAccessFwk } // namespace OHOS \ No newline at end of file diff --git a/frameworks/innerkits/file_access/src/napi_common_fileaccess.cpp b/frameworks/innerkits/file_access/src/napi_common_fileaccess.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dcd39862560a49f8e69272dcfa33dcef43b63ecb --- /dev/null +++ b/frameworks/innerkits/file_access/src/napi_common_fileaccess.cpp @@ -0,0 +1,319 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "napi_common_fileaccess.h" + +#include "file_access_framework_errno.h" +#include "hilog_wrapper.h" + +namespace OHOS { +namespace FileAccessFwk { +using namespace OHOS::AppExecFwk; +bool UnwrapInt64ByPropertyName(napi_env env, napi_value param, const char *propertyName, int64_t &value) +{ + napi_value jsValue = GetPropertyValueByPropertyName(env, param, propertyName, napi_number); + if (jsValue != nullptr) { + return UnwrapInt64FromJS2(env, jsValue, value); + } else { + return false; + } +} + +napi_value WrapUint32ToJS(napi_env env, uint32_t value) +{ + napi_value result = nullptr; + NAPI_CALL(env, napi_create_uint32(env, value, &result)); + return result; +} + +uint32_t UnwrapUint32FromJS(napi_env env, napi_value param, uint32_t defaultValue) +{ + uint32_t value = defaultValue; + if (napi_get_value_uint32(env, param, &value) == napi_ok) { + return value; + } else { + return defaultValue; + } +} + +bool UnwrapUint32FromJS2(napi_env env, napi_value param, uint32_t &value) +{ + bool result = false; + if (napi_get_value_uint32(env, param, &value) == napi_ok) { + result = true; + } + return result; +} + +bool UnwrapUint32ByPropertyName(napi_env env, napi_value param, const char *propertyName, uint32_t &value) +{ + napi_value jsValue = GetPropertyValueByPropertyName(env, param, propertyName, napi_number); + if (jsValue != nullptr) { + return UnwrapUint32FromJS2(env, jsValue, value); + } else { + return false; + } +} + +napi_value WrapBigIntUint64ToJS(napi_env env, uint64_t value) +{ + napi_value result = nullptr; + NAPI_CALL(env, napi_create_bigint_uint64(env, value, &result)); + return result; +} + +uint64_t UnwrapBigIntUint64FromJS(napi_env env, napi_value param, uint64_t defaultValue) +{ + bool lossless = true; + uint64_t value = defaultValue; + if (napi_get_value_bigint_uint64(env, param, &value, &lossless) == napi_ok) { + return value; + } else { + return defaultValue; + } +} + +bool UnwrapBigIntUint64FromJS2(napi_env env, napi_value param, uint64_t &defaultValue) +{ + bool lossless = true; + if (napi_get_value_bigint_uint64(env, param, &defaultValue, &lossless) == napi_ok) { + return true; + } else { + return false; + } +} + +bool UnwrapBigIntUint64ByPropertyName(napi_env env, napi_value param, const char *propertyName, uint64_t &value) +{ + napi_value jsValue = GetPropertyValueByPropertyName(env, param, propertyName, napi_bigint); + if (jsValue != nullptr) { + return UnwrapBigIntUint64FromJS2(env, jsValue, value); + } else { + return false; + } +} + +napi_value WrapFileInfo(napi_env env, const FileInfo &fileInfo) +{ + napi_value jsObject = nullptr; + napi_value jsValue = nullptr; + + NAPI_CALL(env, napi_create_object(env, &jsObject)); + + jsValue = nullptr; + jsValue = OHOS::AppExecFwk::WrapStringToJS(env, fileInfo.uri.ToString()); + SetPropertyValueByPropertyName(env, jsObject, "uri", jsValue); + + jsValue = nullptr; + jsValue = OHOS::AppExecFwk::WrapStringToJS(env, fileInfo.fileName); + SetPropertyValueByPropertyName(env, jsObject, "fileName", jsValue); + + jsValue = nullptr; + jsValue = OHOS::AppExecFwk::WrapStringToJS(env, fileInfo.mode); + SetPropertyValueByPropertyName(env, jsObject, "mode", jsValue); + + jsValue = nullptr; + jsValue = OHOS::AppExecFwk::WrapInt64ToJS(env, fileInfo.size); + SetPropertyValueByPropertyName(env, jsObject, "size", jsValue); + + jsValue = nullptr; + jsValue = OHOS::AppExecFwk::WrapInt64ToJS(env, fileInfo.mtime); + SetPropertyValueByPropertyName(env, jsObject, "mtime", jsValue); + + jsValue = nullptr; + jsValue = OHOS::AppExecFwk::WrapStringToJS(env, fileInfo.mimeType); + SetPropertyValueByPropertyName(env, jsObject, "mimeType", jsValue); + + return jsObject; +} + +bool UnwrapFileInfo(napi_env env, napi_value param, FileInfo &fileInfo) +{ + if (!IsTypeForNapiValue(env, param, napi_object)) { + return false; + } + + std::string natValueString(""); + if (OHOS::AppExecFwk::UnwrapStringByPropertyName(env, param, "uri", natValueString)) { + fileInfo.uri = Uri(natValueString); + } + + natValueString = ""; + if (OHOS::AppExecFwk::UnwrapStringByPropertyName(env, param, "fileName", natValueString)) { + fileInfo.fileName = natValueString; + } + + natValueString = ""; + if (OHOS::AppExecFwk::UnwrapStringByPropertyName(env, param, "mode", natValueString)) { + fileInfo.mode = natValueString; + } + + int64_t natValueInt64 = ERR_OK; + if (UnwrapInt64ByPropertyName(env, param, "size", natValueInt64)) { + fileInfo.size = natValueInt64; + } + + natValueInt64 = ERR_OK; + if (UnwrapInt64ByPropertyName(env, param, "mtime", natValueInt64)) { + fileInfo.mtime = natValueInt64; + } + + natValueString = ""; + if (OHOS::AppExecFwk::UnwrapStringByPropertyName(env, param, "mimeType", natValueString)) { + fileInfo.mimeType = natValueString; + } + + return true; +} + +napi_value WrapArrayFileInfoToJS(napi_env env, const std::vector &fileInfoVec) +{ + napi_value jsArray = nullptr; + napi_value jsValue = nullptr; + uint32_t index = ERR_OK; + + NAPI_CALL(env, napi_create_array(env, &jsArray)); + for (uint32_t i = 0; i < fileInfoVec.size(); i++) { + jsValue = WrapFileInfo(env, fileInfoVec[i]); + if (napi_set_element(env, jsArray, index, jsValue) == napi_ok) { + index++; + } + } + return jsArray; +} + +bool UnwrapArrayFileInfoFromJS(napi_env env, napi_value param, std::vector &fileInfoVec) +{ + uint32_t arraySize = ERR_OK; + napi_value jsValue = nullptr; + + if (!IsArrayForNapiValue(env, param, arraySize)) { + return false; + } + + fileInfoVec.clear(); + for (uint32_t i = 0; i < arraySize; i++) { + jsValue = nullptr; + FileInfo fileInfo; + if (napi_get_element(env, param, i, &jsValue) != napi_ok) { + return false; + } + + if (!UnwrapFileInfo(env, jsValue, fileInfo)) { + return false; + } + + fileInfoVec.push_back(fileInfo); + } + return true; +} + +napi_value WrapDeviceInfo(napi_env env, const DeviceInfo &deviceInfo) +{ + napi_value jsObject = nullptr; + napi_value jsValue = nullptr; + + NAPI_CALL(env, napi_create_object(env, &jsObject)); + + jsValue = nullptr; + jsValue = OHOS::AppExecFwk::WrapStringToJS(env, deviceInfo.uri.ToString()); + SetPropertyValueByPropertyName(env, jsObject, "uri", jsValue); + + jsValue = nullptr; + jsValue = OHOS::AppExecFwk::WrapStringToJS(env, deviceInfo.displayName); + SetPropertyValueByPropertyName(env, jsObject, "displayName", jsValue); + + jsValue = nullptr; + jsValue = OHOS::AppExecFwk::WrapStringToJS(env, deviceInfo.deviceId); + SetPropertyValueByPropertyName(env, jsObject, "deviceId", jsValue); + + jsValue = nullptr; + jsValue = WrapUint32ToJS(env, deviceInfo.flags); + SetPropertyValueByPropertyName(env, jsObject, "flags", jsValue); + + return jsObject; +} + +bool UnwrapDeviceInfo(napi_env env, napi_value param, DeviceInfo &deviceInfo) +{ + if (!IsTypeForNapiValue(env, param, napi_object)) { + return false; + } + + std::string natValueString(""); + if (OHOS::AppExecFwk::UnwrapStringByPropertyName(env, param, "uri", natValueString)) { + deviceInfo.uri = Uri(natValueString); + } + + natValueString = ""; + if (OHOS::AppExecFwk::UnwrapStringByPropertyName(env, param, "displayName", natValueString)) { + deviceInfo.displayName = natValueString; + } + + natValueString = ""; + if (OHOS::AppExecFwk::UnwrapStringByPropertyName(env, param, "deviceId", natValueString)) { + deviceInfo.deviceId = natValueString; + } + + uint32_t natValueUint32 = ERR_OK; + if (UnwrapUint32ByPropertyName(env, param, "flags", natValueUint32)) { + deviceInfo.flags = natValueUint32; + } + return true; +} + +napi_value WrapArrayDeviceInfoToJS(napi_env env, const std::vector &deviceInfoVec) +{ + napi_value jsArray = nullptr; + napi_value jsValue = nullptr; + uint32_t index = ERR_OK; + + NAPI_CALL(env, napi_create_array(env, &jsArray)); + for (uint32_t i = 0; i < deviceInfoVec.size(); i++) { + jsValue = WrapDeviceInfo(env, deviceInfoVec[i]); + if (napi_set_element(env, jsArray, index, jsValue) == napi_ok) { + index++; + } + } + return jsArray; +} + +bool UnwrapArrayDeviceInfoFromJS(napi_env env, napi_value param, std::vector &deviceInfoVec) +{ + uint32_t arraySize = ERR_OK; + napi_value jsValue = nullptr; + + if (!IsArrayForNapiValue(env, param, arraySize)) { + return false; + } + + deviceInfoVec.clear(); + for (uint32_t i = 0; i < arraySize; i++) { + jsValue = nullptr; + DeviceInfo deviceInfo; + if (napi_get_element(env, param, i, &jsValue) != napi_ok) { + return false; + } + + if (!UnwrapDeviceInfo(env, jsValue, deviceInfo)) { + return false; + } + + deviceInfoVec.push_back(deviceInfo); + } + return true; +} +} // namespace FileAccessFwk +} // namespace OHOS diff --git a/utils/file_access_framework_errno.h b/utils/file_access_framework_errno.h new file mode 100644 index 0000000000000000000000000000000000000000..67964eee9f32ab09aa3170ff52741031833f6272 --- /dev/null +++ b/utils/file_access_framework_errno.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef FILE_ACCESS_FRAMEWORK_ERRNO_H +#define FILE_ACCESS_FRAMEWORK_ERRNO_H +#include "errors.h" + +namespace OHOS { +namespace FileAccessFwk { +enum { + MODULE_FILE_ACCESS_FRAMEWORK = 0x01 +}; +constexpr ErrCode BASE_OFFSET = ErrCodeOffset(SUBSYS_FILEMANAGEMENT, MODULE_FILE_ACCESS_FRAMEWORK); +enum { + ERR_OK = 0, + ERR_ERROR = -1, + ERR_IPC_ERROR = BASE_OFFSET, // ipc error + ERR_PERMISSION_DENIED, // no permission + ERR_INVALID_FD, // invalid fd + ERR_INVALID_URI, // invalid uri + ERR_URI_CHECK, // check uri head fail + ERR_CREATE // create file/dir fail +}; +} // namespace FileAccessFwk +} // namespace OHOS +#endif // FILE_ACCESS_FRAMEWORK_ERRNO_H \ No newline at end of file