From b603e6b64ec2a642af5659173fe2a22269acd21f Mon Sep 17 00:00:00 2001 From: linjun9528 Date: Thu, 14 Jul 2022 10:36:03 +0800 Subject: [PATCH 1/3] add notify code Signed-off-by: linjun9528 --- frameworks/innerkits/file_access/BUILD.gn | 7 + .../include/file_access_ext_ability.h | 12 +- .../include/file_access_ext_proxy.h | 8 +- .../include/file_access_ext_stub.h | 2 + .../include/file_access_ext_stub_impl.h | 3 +- .../file_access/include/file_access_helper.h | 8 +- .../include/ifile_access_ext_base.h | 7 +- .../include/js_file_access_ext_ability.h | 1 + .../notify/file_access_notify_client.h | 38 +++++ .../notify/file_access_notify_common.h | 30 ++++ .../notify/file_access_notify_manager.h | 61 ++++++++ .../include/notify/file_access_notify_proxy.h | 36 +++++ .../include/notify/file_access_notify_stub.h | 32 +++++ .../include/notify/ifile_access_notify.h | 37 +++++ .../include/notify/inotify_callback.h | 30 ++++ .../src/file_access_ext_ability.cpp | 50 +++++++ .../file_access/src/file_access_ext_proxy.cpp | 52 +++++++ .../file_access/src/file_access_ext_stub.cpp | 42 ++++++ .../src/file_access_ext_stub_impl.cpp | 28 ++++ .../file_access/src/file_access_helper.cpp | 44 ++++++ .../src/js_file_access_ext_ability.cpp | 35 +++++ .../src/notify/file_access_notify_client.cpp | 37 +++++ .../src/notify/file_access_notify_manager.cpp | 132 ++++++++++++++++++ .../src/notify/file_access_notify_proxy.cpp | 50 +++++++ .../src/notify/file_access_notify_stub.cpp | 50 +++++++ .../file_access_ext_ability.js | 5 +- .../kits/napi/file_access_module/BUILD.gn | 5 +- .../napi_fileaccess_helper.cpp | 62 +++++++- .../napi_fileaccess_helper.h | 2 + .../napi_notify_callback.cpp | 90 ++++++++++++ .../file_access_module/napi_notify_callback.h | 50 +++++++ .../FileExtensionAbility.ts | 16 ++- .../ets/FileExtensionAbility/VolumeManager.ts | 6 +- utils/file_access_framework_errno.h | 7 + 34 files changed, 1059 insertions(+), 16 deletions(-) create mode 100644 frameworks/innerkits/file_access/include/notify/file_access_notify_client.h create mode 100644 frameworks/innerkits/file_access/include/notify/file_access_notify_common.h create mode 100644 frameworks/innerkits/file_access/include/notify/file_access_notify_manager.h create mode 100644 frameworks/innerkits/file_access/include/notify/file_access_notify_proxy.h create mode 100644 frameworks/innerkits/file_access/include/notify/file_access_notify_stub.h create mode 100644 frameworks/innerkits/file_access/include/notify/ifile_access_notify.h create mode 100644 frameworks/innerkits/file_access/include/notify/inotify_callback.h create mode 100644 frameworks/innerkits/file_access/src/notify/file_access_notify_client.cpp create mode 100644 frameworks/innerkits/file_access/src/notify/file_access_notify_manager.cpp create mode 100644 frameworks/innerkits/file_access/src/notify/file_access_notify_proxy.cpp create mode 100644 frameworks/innerkits/file_access/src/notify/file_access_notify_stub.cpp create mode 100644 interfaces/kits/napi/file_access_module/napi_notify_callback.cpp create mode 100644 interfaces/kits/napi/file_access_module/napi_notify_callback.h diff --git a/frameworks/innerkits/file_access/BUILD.gn b/frameworks/innerkits/file_access/BUILD.gn index 1fd54251..01943788 100644 --- a/frameworks/innerkits/file_access/BUILD.gn +++ b/frameworks/innerkits/file_access/BUILD.gn @@ -39,6 +39,7 @@ config("ability_public_config") { visibility = [ ":*" ] include_dirs = [ "include", + "include/notify", "${BASE_DIR}/utils", "${ability_runtime_kits_path}/appkit/native/ability_runtime/app", "${ability_runtime_kits_path}/appkit/native/app/include", @@ -56,6 +57,10 @@ ohos_shared_library("file_access_extension_ability_kit") { "src/file_access_ext_stub.cpp", "src/file_access_ext_stub_impl.cpp", "src/file_access_helper.cpp", + "src/notify/file_access_notify_client.cpp", + "src/notify/file_access_notify_manager.cpp", + "src/notify/file_access_notify_stub.cpp", + "src/notify/file_access_notify_proxy.cpp", "src/js_file_access_ext_ability.cpp", "src/napi_common_fileaccess.cpp", ] @@ -79,6 +84,7 @@ ohos_shared_library("file_access_extension_ability_kit") { "ability_runtime:runtime", "ability_runtime:wantagent_innerkits", "access_token:libaccesstoken_sdk", + "eventhandler:libeventhandler", "hitrace_native:hitrace_meter", "ipc:ipc_core", "ipc_js:rpc", @@ -109,6 +115,7 @@ ohos_shared_library("file_access_extension_ability_module") { "ability_base:want", "ability_runtime:runtime", "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", "utils_base:utils", ] 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 7689afb0..2a80937d 100644 --- a/frameworks/innerkits/file_access/include/file_access_ext_ability.h +++ b/frameworks/innerkits/file_access/include/file_access_ext_ability.h @@ -13,11 +13,12 @@ * limitations under the License. */ -#ifndef FILE_EXT_ABILITY_H -#define FILE_EXT_ABILITY_H +#ifndef __FILE_ACCESS_EXT_ABILITY_H__ +#define __FILE_ACCESS_EXT_ABILITY_H__ #include "extension_base.h" #include "file_access_extension_info.h" +#include "file_access_notify_manager.h" namespace OHOS { namespace AbilityRuntime { @@ -48,10 +49,15 @@ public: virtual std::vector ListFile(const Uri &sourceFile); virtual std::vector GetRoots(); + virtual int RegisterNotify(sptr ¬ify); + virtual int UnregisterNotify(sptr ¬ify); + virtual int Notify(const Uri &uri, const NotifyType notifyType); static void SetCreator(const CreatorFunc& creator); private: + bool GetNotifyManager(); static CreatorFunc creator_; + std::unique_ptr notifyManager_; }; } // namespace FileAccessFwk } // namespace OHOS -#endif // FILE_EXT_ABILITY_H \ No newline at end of file +#endif // __FILE_ACCESS_EXT_ABILITY_H__ \ No newline at end of file diff --git a/frameworks/innerkits/file_access/include/file_access_ext_proxy.h b/frameworks/innerkits/file_access/include/file_access_ext_proxy.h index d4918e22..927e8967 100644 --- a/frameworks/innerkits/file_access/include/file_access_ext_proxy.h +++ b/frameworks/innerkits/file_access/include/file_access_ext_proxy.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef FILE_EXT_PROXY_H -#define FILE_EXT_PROXY_H +#ifndef __FILE_ACCESS_EXT_PROXY_H__ +#define __FILE_ACCESS_EXT_PROXY_H__ #include @@ -38,9 +38,11 @@ public: virtual std::vector ListFile(const Uri &sourceFile) override; virtual std::vector GetRoots() override; + virtual int RegisterNotify(sptr ¬ify) override; + virtual int UnregisterNotify(sptr ¬ify) override; private: static inline BrokerDelegator delegator_; }; } // namespace FileAccessFwk } // namespace OHOS -#endif // FILE_EXT_PROXY_H +#endif // __FILE_ACCESS_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 index 73c1552a..fe431f32 100644 --- a/frameworks/innerkits/file_access/include/file_access_ext_stub.h +++ b/frameworks/innerkits/file_access/include/file_access_ext_stub.h @@ -39,6 +39,8 @@ private: ErrCode CmdListFile(MessageParcel &data, MessageParcel &reply); ErrCode CmdGetRoots(MessageParcel &data, MessageParcel &reply); bool CheckCallingPermission(const std::string &permission); + ErrCode CmdRegisterNotify(MessageParcel &data, MessageParcel &reply); + ErrCode CmdUnregisterNotify(MessageParcel &data, MessageParcel &reply); using RequestFuncType = int (FileAccessExtStub::*)(MessageParcel &data, MessageParcel &reply); std::map stubFuncMap_; }; 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 index 1cd130ba..46d65d15 100644 --- a/frameworks/innerkits/file_access/include/file_access_ext_stub_impl.h +++ b/frameworks/innerkits/file_access/include/file_access_ext_stub_impl.h @@ -40,7 +40,8 @@ public: int Rename(const Uri &sourceFile, const std::string &displayName, Uri &newFile) override; std::vector ListFile(const Uri &sourceFileUri) override; std::vector GetRoots() override; - + int RegisterNotify(sptr ¬ify) override; + int UnregisterNotify(sptr ¬ify) override; private: std::shared_ptr GetOwner(); std::shared_ptr extension_; diff --git a/frameworks/innerkits/file_access/include/file_access_helper.h b/frameworks/innerkits/file_access/include/file_access_helper.h index be151480..9e19e07e 100644 --- a/frameworks/innerkits/file_access/include/file_access_helper.h +++ b/frameworks/innerkits/file_access/include/file_access_helper.h @@ -16,14 +16,17 @@ #ifndef FILE_ACCESS_HELPER_H #define FILE_ACCESS_HELPER_H +#include #include #include #include "context.h" #include "file_access_ext_connection.h" #include "file_access_extension_info.h" +#include "file_access_notify_client.h" #include "hilog_wrapper.h" #include "ifile_access_ext_base.h" +#include "inotify_callback.h" #include "uri.h" #include "want.h" @@ -50,7 +53,8 @@ public: int Rename(Uri &sourceFile, const std::string &displayName, Uri &newFile); std::vector ListFile(Uri &sourceFile); std::vector GetRoots(); - + int On(std::shared_ptr &callback); + int Off(); private: FileAccessHelper(const std::shared_ptr &context, const AAFwk::Want &want, const sptr &fileAccessExtProxy); @@ -58,13 +62,13 @@ private: 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; + sptr notifyClient_ = nullptr; }; class FileAccessDeathRecipient : public IRemoteObject::DeathRecipient { diff --git a/frameworks/innerkits/file_access/include/ifile_access_ext_base.h b/frameworks/innerkits/file_access/include/ifile_access_ext_base.h index fdc837b8..e24d01b2 100644 --- a/frameworks/innerkits/file_access/include/ifile_access_ext_base.h +++ b/frameworks/innerkits/file_access/include/ifile_access_ext_base.h @@ -22,6 +22,8 @@ #include #include "file_access_extension_info.h" +#include "file_access_framework_errno.h" +#include "ifile_access_notify.h" #include "uri.h" namespace OHOS { @@ -39,6 +41,8 @@ public: CMD_RENAME, CMD_LIST_FILE, CMD_GET_ROOTS + CMD_REGISTER_NOTIFY, + CMD_UNREGISTER_NOTIFY, }; virtual int OpenFile(const Uri &uri, int flags) = 0; @@ -47,9 +51,10 @@ public: 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; + virtual int RegisterNotify(sptr ¬ify) = 0; + virtual int UnregisterNotify(sptr ¬ify) = 0; }; } // namespace FileAccessFwk } // namespace OHOS 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 49d26194..cef2bdab 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 @@ -67,6 +67,7 @@ public: 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); + static NativeValue* FuncCallback(NativeEngine* engine, NativeCallbackInfo* info); void GetSrcPath(std::string &srcPath); JsRuntime &jsRuntime_; diff --git a/frameworks/innerkits/file_access/include/notify/file_access_notify_client.h b/frameworks/innerkits/file_access/include/notify/file_access_notify_client.h new file mode 100644 index 00000000..e01940b6 --- /dev/null +++ b/frameworks/innerkits/file_access/include/notify/file_access_notify_client.h @@ -0,0 +1,38 @@ +/* + * 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_NOTIFY_CLIENT_H__ +#define __FILE_ACCESS_NOTIFY_CLIENT_H__ + +#include + +#include "file_access_notify_stub.h" +#include "inotify_callback.h" +#include "iremote_object.h" + +namespace OHOS { +namespace FileAccessFwk { +class FileAccessNotifyClient final : public FileAccessNotifyStub { +public: + FileAccessNotifyClient(std::shared_ptr ¬ifyCallback); + ~FileAccessNotifyClient(); + void OnNotify(const Uri &uri, const NotifyType notifyType) override; + +private: + std::shared_ptr notifyCallback_; +}; +} // namespace FileAccessFwk +} // namespace OHOS +#endif // __FILE_ACCESS_NOTIFY_CLIENT_H__ \ No newline at end of file diff --git a/frameworks/innerkits/file_access/include/notify/file_access_notify_common.h b/frameworks/innerkits/file_access/include/notify/file_access_notify_common.h new file mode 100644 index 00000000..ab6aa335 --- /dev/null +++ b/frameworks/innerkits/file_access/include/notify/file_access_notify_common.h @@ -0,0 +1,30 @@ +/* + * 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_NOTIFY_COMMON_H__ +#define __FILE_ACCESS_NOTIFY_COMMON_H__ + +namespace OHOS { +namespace FileAccessFwk { +enum NotifyType { + NOTIFY_DEVICE_ONLINE = 1, + NOTIFY_DEVICE_OFFLINE, + NOTIFY_FILE_CREATE, + NOTIFY_FILE_DELETE, + NOTIFY_FILE_MODIFY +}; +} // namespace FileAccessFwk +} // namespace OHOS +#endif // __FILE_ACCESS_NOTIFY_COMMON_H__ \ No newline at end of file diff --git a/frameworks/innerkits/file_access/include/notify/file_access_notify_manager.h b/frameworks/innerkits/file_access/include/notify/file_access_notify_manager.h new file mode 100644 index 00000000..6669c733 --- /dev/null +++ b/frameworks/innerkits/file_access/include/notify/file_access_notify_manager.h @@ -0,0 +1,61 @@ +/* + * 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_NOTIFY_MANAGER_H__ +#define __FILE_ACCESS_NOTIFY_MANAGER_H__ + +#include +#include +#include + +#include "event_handler.h" +#include "ifile_access_notify.h" +#include "iremote_object.h" + +namespace OHOS { +namespace FileAccessFwk { +using EventHandler = OHOS::AppExecFwk::EventHandler; +class FileAccessNotifyManager final : public std::enable_shared_from_this { +public: + using NotifyMapType = std::map, sptr>; + + FileAccessNotifyManager(); + ~FileAccessNotifyManager(); + + int RegisterNotify(sptr ¬ify); + int UnregisterNotify(sptr ¬ify); + int Notify(const Uri uri, const NotifyType notifyType); + +private: + void OnCallBackDied(const wptr &remote); + bool AddNotifyToMap(const sptr ¬ify); + bool RemoveNotifyFromMap(const sptr &remote); + NotifyMapType notifyMap_; + static std::mutex notifyMapMutex_; +}; + +class FileAccessNotifyCallbackRecipient : public IRemoteObject::DeathRecipient { +public: + using RemoteDiedHandler = std::function &)>; + FileAccessNotifyCallbackRecipient(RemoteDiedHandler handler); + virtual ~FileAccessNotifyCallbackRecipient(); + virtual void OnRemoteDied(const wptr &remote); + +private: + RemoteDiedHandler handler_; +}; +} // namespace FileAccessFwk +} // namespace OHOS +#endif // __FILE_ACCESS_NOTIFY_MANAGER_H__ \ No newline at end of file diff --git a/frameworks/innerkits/file_access/include/notify/file_access_notify_proxy.h b/frameworks/innerkits/file_access/include/notify/file_access_notify_proxy.h new file mode 100644 index 00000000..092064e4 --- /dev/null +++ b/frameworks/innerkits/file_access/include/notify/file_access_notify_proxy.h @@ -0,0 +1,36 @@ +/* + * 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_NOTIFY_PROXY_H__ +#define __FILE_ACCESS_NOTIFY_PROXY_H__ + +#include "ifile_access_notify.h" +#include "iremote_broker.h" +#include "iremote_proxy.h" +#include "uri.h" + +namespace OHOS { +namespace FileAccessFwk { +class FileAccessNotifyProxy : public IRemoteProxy { +public: + explicit FileAccessNotifyProxy(const sptr &impl); + ~FileAccessNotifyProxy() = default; + void OnNotify(const Uri &uri, const NotifyType notifyType) override; +private: + static inline BrokerDelegator delegator_; +}; +} // namespace FileAccessFwk +} // namespace OHOS +#endif // __FILE_ACCESS_NOTIFY_PROXY_H__ \ No newline at end of file diff --git a/frameworks/innerkits/file_access/include/notify/file_access_notify_stub.h b/frameworks/innerkits/file_access/include/notify/file_access_notify_stub.h new file mode 100644 index 00000000..3e466f8c --- /dev/null +++ b/frameworks/innerkits/file_access/include/notify/file_access_notify_stub.h @@ -0,0 +1,32 @@ +/* + * 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_NOTIFY_STUB_H__ +#define __FILE_ACCESS_NOTIFY_STUB_H__ + +#include "ifile_access_notify.h" +#include "iremote_stub.h" +#include "uri.h" + +namespace OHOS { +namespace FileAccessFwk { +class FileAccessNotifyStub : public IRemoteStub { +public: + virtual int OnRemoteRequest(uint32_t code, MessageParcel &data, + MessageParcel &reply, MessageOption &option) override; +}; +} // namespace FileAccessFwk +} // namespace OHOS +#endif // __FILE_ACCESS_NOTIFY_STUB_H__ \ No newline at end of file diff --git a/frameworks/innerkits/file_access/include/notify/ifile_access_notify.h b/frameworks/innerkits/file_access/include/notify/ifile_access_notify.h new file mode 100644 index 00000000..18fdaaea --- /dev/null +++ b/frameworks/innerkits/file_access/include/notify/ifile_access_notify.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 __I_FILE_ACCESS_NOTIFY_H__ +#define __I_FILE_ACCESS_NOTIFY_H__ + +#include "file_access_notify_common.h" +#include "iremote_broker.h" +#include "uri.h" + +namespace OHOS { +namespace FileAccessFwk { +class IFileAccessNotify : public IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.FileAccessFwk.IFileAccessNotify"); + + enum { + CMD_ON_NOTIFY = 1, + }; + + virtual void OnNotify(const Uri &uri, const NotifyType notifyType) = 0; +}; +} // namespace FileAccessFwk +} // namespace OHOS +#endif // __I_FILE_ACCESS_NOTIFY_H__ \ No newline at end of file diff --git a/frameworks/innerkits/file_access/include/notify/inotify_callback.h b/frameworks/innerkits/file_access/include/notify/inotify_callback.h new file mode 100644 index 00000000..e9e0afcc --- /dev/null +++ b/frameworks/innerkits/file_access/include/notify/inotify_callback.h @@ -0,0 +1,30 @@ +/* + * 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_NOTIFY_CALLBACK_H__ +#define __I_NOTIFY_CALLBACK_H__ + +#include "file_access_notify_common.h" +#include "uri.h" + +namespace OHOS { +namespace FileAccessFwk { +class INotifyCallback { +public: + virtual void OnNotify(const Uri &uri, const NotifyType notifyType) = 0; +}; +} // namespace FileAccessFwk +} // namespace OHOS +#endif // __I_NOTIFY_CALLBACK_H__ \ No newline at end of file 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 a570e63d..5b42a91a 100644 --- a/frameworks/innerkits/file_access/src/file_access_ext_ability.cpp +++ b/frameworks/innerkits/file_access/src/file_access_ext_ability.cpp @@ -99,5 +99,55 @@ std::vector FileAccessExtAbility::GetRoots() std::vector vec; return vec; } + +bool FileAccessExtAbility::GetNotifyManager() +{ + if (notifyManager_ == nullptr) { + notifyManager_ = std::make_unique(); + if (notifyManager_ == nullptr) { + return false; + } + } + return true; +} + +int FileAccessExtAbility::RegisterNotify(sptr ¬ify) +{ + if (!GetNotifyManager()) { + HILOG_ERROR("GetNotifyManager fail."); + return ERR_ERROR; + } + int ret = notifyManager_->RegisterNotify(notify); + if (ret != ERR_OK) { + HILOG_ERROR("NotifyManager register notify fail."); + } + return ret; +} + +int FileAccessExtAbility::UnregisterNotify(sptr ¬ify) +{ + if (!GetNotifyManager()) { + HILOG_ERROR("GetNotifyManager fail."); + return ERR_ERROR; + } + int ret = notifyManager_->UnregisterNotify(notify); + if (ret != ERR_OK) { + HILOG_ERROR("NotifyManager unregister notify fail."); + } + return ret; +} + +int FileAccessExtAbility::Notify(const Uri &uri, const NotifyType notifyType) +{ + if (!GetNotifyManager()) { + HILOG_ERROR("GetNotifyManager fail."); + return ERR_ERROR; + } + int ret = notifyManager_->Notify(uri, notifyType); + if (ret != ERR_OK) { + HILOG_ERROR("NotifyManager handle notify fail."); + } + return ret; +} } // 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 index 46a75442..61c93fb7 100644 --- a/frameworks/innerkits/file_access/src/file_access_ext_proxy.cpp +++ b/frameworks/innerkits/file_access/src/file_access_ext_proxy.cpp @@ -395,5 +395,57 @@ std::vector FileAccessExtProxy::GetRoots() FinishTrace(HITRACE_TAG_FILEMANAGEMENT); return vec; } + +int FileAccessExtProxy::RegisterNotify(sptr ¬ify) +{ + MessageParcel data; + if (!data.WriteInterfaceToken(FileAccessExtProxy::GetDescriptor())) { + HILOG_ERROR("WriteInterfaceToken failed"); + return ERR_PARCEL_ERROR; + } + if (!data.WriteRemoteObject(notify->AsObject())) { + HILOG_ERROR("write subscribe type or parcel failed."); + return ERR_PARCEL_ERROR; + } + MessageParcel reply; + MessageOption option; + int err = Remote()->SendRequest(CMD_REGISTER_NOTIFY, data, reply, option); + if (err != ERR_OK) { + HILOG_ERROR("fail to SendRequest. err: %{public}d", err); + return err; + } + err = reply.ReadInt32(); + if (err != ERR_OK) { + HILOG_ERROR("fail to RegisterNotify. err: %{public}d", err); + return err; + } + return err; +} + +int FileAccessExtProxy::UnregisterNotify(sptr ¬ify) +{ + MessageParcel data; + if (!data.WriteInterfaceToken(FileAccessExtProxy::GetDescriptor())) { + HILOG_ERROR("WriteInterfaceToken failed"); + return ERR_PARCEL_ERROR; + } + if (!data.WriteRemoteObject(notify->AsObject())) { + HILOG_ERROR("write subscribe type or parcel failed."); + return ERR_PARCEL_ERROR; + } + MessageParcel reply; + MessageOption option; + int err = Remote()->SendRequest(CMD_UNREGISTER_NOTIFY, data, reply, option); + if (err != ERR_OK) { + HILOG_ERROR("fail to SendRequest. err: %{public}d", err); + return err; + } + err = reply.ReadInt32(); + if (err != ERR_OK) { + HILOG_ERROR("fail to UnregisterNotify. err: %{public}d", err); + return err; + } + return err; +} } // 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 index ddc2ee80..a7c14506 100644 --- a/frameworks/innerkits/file_access/src/file_access_ext_stub.cpp +++ b/frameworks/innerkits/file_access/src/file_access_ext_stub.cpp @@ -36,6 +36,8 @@ FileAccessExtStub::FileAccessExtStub() stubFuncMap_[CMD_RENAME] = &FileAccessExtStub::CmdRename; stubFuncMap_[CMD_LIST_FILE] = &FileAccessExtStub::CmdListFile; stubFuncMap_[CMD_GET_ROOTS] = &FileAccessExtStub::CmdGetRoots; + stubFuncMap_[CMD_REGISTER_NOTIFY] = &FileAccessExtStub::CmdRegisterNotify; + stubFuncMap_[CMD_UNREGISTER_NOTIFY] = &FileAccessExtStub::CmdUnregisterNotify; } FileAccessExtStub::~FileAccessExtStub() @@ -386,5 +388,45 @@ bool FileAccessExtStub::CheckCallingPermission(const std::string &permission) FinishTrace(HITRACE_TAG_FILEMANAGEMENT); return true; } + +ErrCode FileAccessExtStub::CmdRegisterNotify(MessageParcel &data, MessageParcel &reply) +{ + auto remote = data.ReadRemoteObject(); + if (remote == nullptr) { + HILOG_INFO("get remote obj fail."); + return ERR_PARCEL_ERROR; + } + auto notify = iface_cast(remote); + if (notify == nullptr) { + HILOG_INFO("get notify fail"); + return ERR_PARCEL_ERROR; + } + int ret = RegisterNotify(notify); + if (!reply.WriteInt32(ret)) { + HILOG_ERROR("WriteInt32 failed"); + return ERR_PARCEL_ERROR; + } + return ERR_OK; +} + +ErrCode FileAccessExtStub::CmdUnregisterNotify(MessageParcel &data, MessageParcel &reply) +{ + auto remote = data.ReadRemoteObject(); + if (remote == nullptr) { + HILOG_INFO("get remote obj fail."); + return ERR_PARCEL_ERROR; + } + auto notify = iface_cast(remote); + if (notify == nullptr) { + HILOG_INFO("get notify fail"); + return ERR_PARCEL_ERROR; + } + int ret = UnregisterNotify(notify); + if (!reply.WriteInt32(ret)) { + HILOG_ERROR("WriteInt32 failed"); + return ERR_PARCEL_ERROR; + } + return ERR_OK; +} } // namespace FileAccessFwk } // namespace OHOS \ No newline at end of file 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 index 26fd26e2..834e24e1 100644 --- a/frameworks/innerkits/file_access/src/file_access_ext_stub_impl.cpp +++ b/frameworks/innerkits/file_access/src/file_access_ext_stub_impl.cpp @@ -153,5 +153,33 @@ std::vector FileAccessExtStubImpl::GetRoots() FinishTrace(HITRACE_TAG_FILEMANAGEMENT); return vec; } + +int FileAccessExtStubImpl::RegisterNotify(sptr ¬ify) +{ + auto extension = GetOwner(); + if (extension == nullptr) { + HILOG_ERROR("get extension failed."); + return ERR_ERROR; + } + int ret = extension->RegisterNotify(notify); + if (ret != ERR_OK) { + HILOG_ERROR("RegisterNotify failed."); + } + return ret; +} + +int FileAccessExtStubImpl::UnregisterNotify(sptr ¬ify) +{ + auto extension = GetOwner(); + if (extension == nullptr) { + HILOG_ERROR("get extension failed."); + return ERR_ERROR; + } + int ret = extension->UnregisterNotify(notify); + if (ret != ERR_OK) { + HILOG_ERROR("UnregisterNotify failed."); + } + return ret; +} } // namespace FileAccessFwk } // namespace OHOS \ No newline at end of file diff --git a/frameworks/innerkits/file_access/src/file_access_helper.cpp b/frameworks/innerkits/file_access/src/file_access_helper.cpp index 9a3a497a..8e4e891b 100644 --- a/frameworks/innerkits/file_access/src/file_access_helper.cpp +++ b/frameworks/innerkits/file_access/src/file_access_helper.cpp @@ -272,6 +272,50 @@ std::vector FileAccessHelper::GetRoots() return results; } +int FileAccessHelper::On(std::shared_ptr &callback) +{ + if (notifyClient_ != nullptr) { + HILOG_INFO("notifyClient registered yet."); + int ret = fileAccessExtProxy_->UnregisterNotify(notifyClient_); + if (ret != ERR_OK) { + HILOG_ERROR("fileAccessExtProxy_ unregisterNotify fail"); + } + notifyClient_.clear(); + } + notifyClient_ = new (std::nothrow) FileAccessNotifyClient(callback); + if (notifyClient_ == nullptr) { + HILOG_INFO("new FileAccessNotifyClient fail"); + return ERR_ERROR; + } + if (!GetProxy()) { + HILOG_ERROR("failed with invalid fileAccessExtProxy_"); + return ERR_IPC_ERROR; + } + int ret = fileAccessExtProxy_->RegisterNotify(notifyClient_); + if (ret != ERR_OK) { + HILOG_ERROR("fileAccessExtProxy_ RegisterNotify fail"); + } + return ret; +} + +int FileAccessHelper::Off() +{ + if (notifyClient_ == nullptr) { + HILOG_ERROR("not registered notify"); + return ERR_NOTIFY_NOT_EXIST; + } + if (!GetProxy()) { + HILOG_ERROR("failed with invalid fileAccessExtProxy_"); + return ERR_IPC_ERROR; + } + int ret = fileAccessExtProxy_->UnregisterNotify(notifyClient_); + if (ret != ERR_OK) { + HILOG_ERROR("fileAccessExtProxy_ unregisterNotify fail"); + } + notifyClient_.clear(); + return ret; +} + void FileAccessDeathRecipient::OnRemoteDied(const wptr &remote) { if (handler_) { 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 30764f8d..639bde50 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 @@ -87,6 +87,34 @@ void JsFileAccessExtAbility::Init(const std::shared_ptr &rec FinishTrace(HITRACE_TAG_FILEMANAGEMENT); } +NativeValue* JsFileAccessExtAbility::FuncCallback(NativeEngine* engine, NativeCallbackInfo* info) +{ + if (engine == nullptr || info == nullptr) { + HILOG_INFO("%invalid param."); + return engine->CreateUndefined(); + } + if (info->argc != ARGC_TWO || info->argv[ARGC_ZERO] == nullptr || info->argv[ARGC_ONE] == nullptr) { + HILOG_ERROR("invalid args."); + return engine->CreateUndefined(); + } + std::string uri = UnwrapStringFromJS(reinterpret_cast(engine), + reinterpret_cast(info->argv[ARGC_ZERO])); + NotifyType notifyType = (NotifyType)UnwrapUint32FromJS(reinterpret_cast(engine), + reinterpret_cast(info->argv[ARGC_ONE])); + + if (info->functionInfo == nullptr || info->functionInfo->data == nullptr) { + HILOG_INFO("invalid object."); + return engine->CreateUndefined(); + } + JsFileAccessExtAbility* jsExtension = static_cast(info->functionInfo->data); + if (jsExtension == nullptr) { + HILOG_INFO("invalid JsFileAccessExtAbility."); + return engine->CreateUndefined(); + } + jsExtension->Notify(Uri(uri), notifyType); + return engine->CreateUndefined(); +} + void JsFileAccessExtAbility::OnStart(const AAFwk::Want &want) { StartTrace(HITRACE_TAG_FILEMANAGEMENT, "OnStart"); @@ -97,6 +125,13 @@ void JsFileAccessExtAbility::OnStart(const AAFwk::Want &want) NativeValue* nativeWant = reinterpret_cast(napiWant); NativeValue* argv[] = {nativeWant}; CallObjectMethod("onCreate", argv, ARGC_ONE); + + const std::string funcName = "FuncCallback"; + auto& nativeEngine = jsRuntime_.GetNativeEngine(); + NativeValue* func = nativeEngine.CreateFunction(funcName.c_str(), funcName.length(), + JsFileAccessExtAbility::FuncCallback, this); + NativeValue* argvCallback[] = {func}; + CallObjectMethod("registerCallback", argvCallback, ARGC_ONE); FinishTrace(HITRACE_TAG_FILEMANAGEMENT); } diff --git a/frameworks/innerkits/file_access/src/notify/file_access_notify_client.cpp b/frameworks/innerkits/file_access/src/notify/file_access_notify_client.cpp new file mode 100644 index 00000000..852bd3e2 --- /dev/null +++ b/frameworks/innerkits/file_access/src/notify/file_access_notify_client.cpp @@ -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. + */ + +#include "file_access_notify_client.h" +#include "hilog_wrapper.h" + +namespace OHOS { +namespace FileAccessFwk { +FileAccessNotifyClient::FileAccessNotifyClient(std::shared_ptr ¬ifyCallback) + : notifyCallback_(notifyCallback) +{ +} + +FileAccessNotifyClient::~FileAccessNotifyClient() +{ +} + +void FileAccessNotifyClient::OnNotify(const Uri &uri, const NotifyType notifyType) +{ + if (notifyCallback_ != nullptr) { + notifyCallback_->OnNotify(uri, notifyType); + } +} +} // namespace FileAccessFwk +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/innerkits/file_access/src/notify/file_access_notify_manager.cpp b/frameworks/innerkits/file_access/src/notify/file_access_notify_manager.cpp new file mode 100644 index 00000000..72809ff6 --- /dev/null +++ b/frameworks/innerkits/file_access/src/notify/file_access_notify_manager.cpp @@ -0,0 +1,132 @@ +/* + * 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_notify_manager.h" + +#include "file_access_framework_errno.h" +#include "hilog_wrapper.h" + +namespace OHOS { +namespace FileAccessFwk { +std::mutex FileAccessNotifyManager::notifyMapMutex_; + +FileAccessNotifyManager::FileAccessNotifyManager() +{ +} + +FileAccessNotifyManager::~FileAccessNotifyManager() +{ +} + +int FileAccessNotifyManager::RegisterNotify(sptr ¬ify) +{ + std::lock_guard lock(notifyMapMutex_); + if (!AddNotifyToMap(notify)) { + HILOG_ERROR("the remote obj is nullptr."); + return ERR_INVALID_NOTIFY; + } + return ERR_OK; +} + +int FileAccessNotifyManager::UnregisterNotify(sptr ¬ify) +{ + if (notify == nullptr || notify->AsObject() == nullptr) { + HILOG_ERROR("the remote obj is nullptr."); + return ERR_INVALID_NOTIFY; + } + std::lock_guard lock(notifyMapMutex_); + if (!RemoveNotifyFromMap(notify->AsObject())) { + HILOG_ERROR("remove remote obj from map fail."); + return ERR_REMOVE_NOTIFY_FAIL; + } + return ERR_OK; +} + +int FileAccessNotifyManager::Notify(const Uri uri, const NotifyType notifyType) +{ + std::lock_guard lock(notifyMapMutex_); + for (auto iter = notifyMap_.begin(); iter != notifyMap_.end(); iter++) { + if (iter->first != nullptr) { + iter->first->OnNotify(uri, notifyType); + } + } + return ERR_OK; +} + +bool FileAccessNotifyManager::AddNotifyToMap(const sptr ¬ify) +{ + if (notify == nullptr || notify->AsObject() == nullptr) { + HILOG_ERROR("the death notify obj is nullptr."); + return false; + } + for (auto iter = notifyMap_.begin(); iter != notifyMap_.end(); iter++) { + if (iter->first == notify) { + iter->first->AsObject()->RemoveDeathRecipient(iter->second); + notifyMap_.erase(iter); + } + } + sptr deathRecipient = new FileAccessNotifyCallbackRecipient( + std::bind(&FileAccessNotifyManager::OnCallBackDied, this, std::placeholders::_1)); + notify->AsObject()->AddDeathRecipient(deathRecipient); + notifyMap_.emplace(notify, deathRecipient); + return true; +} + +bool FileAccessNotifyManager::RemoveNotifyFromMap(const sptr &remote) +{ + if (remote == nullptr) { + HILOG_ERROR("the death remote obj is nullptr."); + return false; + } + for (auto iter = notifyMap_.begin(); iter != notifyMap_.end(); iter++) { + if (iter->first->AsObject() == remote) { + iter->first->AsObject()->RemoveDeathRecipient(iter->second); + notifyMap_.erase(iter); + break; + } + } + return true; +} + +void FileAccessNotifyManager::OnCallBackDied(const wptr &remote) +{ + auto object = remote.promote(); + if (object == nullptr) { + HILOG_INFO("the death remote obj is nullptr"); + return; + } + std::lock_guard lock(notifyMapMutex_); + if (!RemoveNotifyFromMap(object)) { + HILOG_ERROR("remove remote obj from map fail."); + return; + } +} + +FileAccessNotifyCallbackRecipient::FileAccessNotifyCallbackRecipient(RemoteDiedHandler handler) : handler_(handler) +{ +} + +FileAccessNotifyCallbackRecipient::~FileAccessNotifyCallbackRecipient() +{ +} + +void FileAccessNotifyCallbackRecipient::OnRemoteDied(const wptr &remote) +{ + if (handler_) { + handler_(remote); + } +} +} // namespace FileAccessFwk +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/innerkits/file_access/src/notify/file_access_notify_proxy.cpp b/frameworks/innerkits/file_access/src/notify/file_access_notify_proxy.cpp new file mode 100644 index 00000000..5bd352b5 --- /dev/null +++ b/frameworks/innerkits/file_access/src/notify/file_access_notify_proxy.cpp @@ -0,0 +1,50 @@ +/* + * 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_notify_proxy.h" + +#include "hilog_wrapper.h" +#include "message_parcel.h" + +namespace OHOS { +namespace FileAccessFwk { +FileAccessNotifyProxy::FileAccessNotifyProxy(const sptr &impl) : IRemoteProxy(impl) +{ +} + +void FileAccessNotifyProxy::OnNotify(const Uri &uri, const NotifyType notifyType) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(FileAccessNotifyProxy::GetDescriptor())) { + HILOG_ERROR("write descriptor failed"); + return; + } + if (!data.WriteParcelable(&uri)) { + HILOG_ERROR("write parcel uri failed"); + return; + } + if (!data.WriteInt32((int32_t)notifyType)) { + HILOG_ERROR("write parcel notifyType failed"); + return; + } + int error = Remote()->SendRequest(CMD_ON_NOTIFY, data, reply, option); + if (error != 0) { + HILOG_ERROR("SendRequest failed, error %d", error); + } +} +} // namespace FileAccessFwk +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/innerkits/file_access/src/notify/file_access_notify_stub.cpp b/frameworks/innerkits/file_access/src/notify/file_access_notify_stub.cpp new file mode 100644 index 00000000..901b38ff --- /dev/null +++ b/frameworks/innerkits/file_access/src/notify/file_access_notify_stub.cpp @@ -0,0 +1,50 @@ +/* + * 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_notify_stub.h" + +#include "file_access_framework_errno.h" +#include "hilog_wrapper.h" +#include "message_parcel.h" + +namespace OHOS { +namespace FileAccessFwk { +int32_t FileAccessNotifyStub::OnRemoteRequest(uint32_t code, MessageParcel &data, + MessageParcel &reply, MessageOption &option) +{ + auto descriptor = FileAccessNotifyStub::GetDescriptor(); + auto remoteDescriptor = data.ReadInterfaceToken(); + if (descriptor != remoteDescriptor) { + HILOG_ERROR("local descriptor is not equal to remote"); + return ERR_ERROR; + } + switch (code) { + case CMD_ON_NOTIFY: { + std::shared_ptr uri(data.ReadParcelable()); + if (uri == nullptr) { + HILOG_ERROR("read parcel uri fail"); + return ERR_PARCEL_ERROR; + } + NotifyType notifyType = (NotifyType)data.ReadInt32(); + OnNotify(*uri, notifyType); + return ERR_OK; + } + default: + HILOG_DEBUG("code error, FileAccessNotifyStub::OnRemoteRequest"); + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); + } +} +} // namespace FileAccessFwk +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/napi/file_access_ext_ability/file_access_ext_ability.js b/interfaces/kits/napi/file_access_ext_ability/file_access_ext_ability.js index 97f0eb6a..9c6da32a 100644 --- a/interfaces/kits/napi/file_access_ext_ability/file_access_ext_ability.js +++ b/interfaces/kits/napi/file_access_ext_ability/file_access_ext_ability.js @@ -17,6 +17,9 @@ class FileAccessExtensionAbility { onCreate(want) { } + registerCallback(callback) { + } + openFile(uri, mode) { return 0; } @@ -36,7 +39,7 @@ class FileAccessExtensionAbility { move(sourceFileUri, targetParentUri) { return ""; } - + rename(sourceFileUri, displayName) { return ""; } diff --git a/interfaces/kits/napi/file_access_module/BUILD.gn b/interfaces/kits/napi/file_access_module/BUILD.gn index fd97e1a0..a0200395 100644 --- a/interfaces/kits/napi/file_access_module/BUILD.gn +++ b/interfaces/kits/napi/file_access_module/BUILD.gn @@ -24,18 +24,20 @@ ohos_shared_library("fileaccess") { "./", "${BASE_DIR}/utils", "${BASE_DIR}/interfaces/kits/napi/common", + "//foundation/distributeddatamgr/distributedfile/utils/filemgmt_libn/include", ] sources = [ "${BASE_DIR}/interfaces/kits/napi/common/file_extension_info_napi.cpp", "napi_fileaccess_helper.cpp", + "napi_notify_callback.cpp", "native_fileaccess_module.cpp", ] deps = [ "${BASE_DIR}/frameworks/innerkits/file_access:file_access_extension_ability_kit", "//foundation/ability/ability_runtime/frameworks/js/napi/inner/napi_common:napi_common", - "//foundation/distributeddatamgr/distributedfile/utils/filemgmt_libn", + "//foundation/distributeddatamgr/distributedfile/utils/filemgmt_libn:filemgmt_libn", ] external_deps = [ @@ -45,6 +47,7 @@ ohos_shared_library("fileaccess") { "ability_runtime:abilitykit_native", "ability_runtime:napi_base_context", "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", "napi:ace_napi", "utils_base:utils", ] diff --git a/interfaces/kits/napi/file_access_module/napi_fileaccess_helper.cpp b/interfaces/kits/napi/file_access_module/napi_fileaccess_helper.cpp index c8edcf9b..f0d2c5cb 100644 --- a/interfaces/kits/napi/file_access_module/napi_fileaccess_helper.cpp +++ b/interfaces/kits/napi/file_access_module/napi_fileaccess_helper.cpp @@ -22,8 +22,10 @@ #include "file_access_helper.h" #include "filemgmt_libn.h" #include "hilog_wrapper.h" +#include "ifile_access_notify.h" #include "napi_base_context.h" #include "napi_common_fileaccess.h" +#include "napi_notify_callback.h" #include "n_val.h" #include "securec.h" #include "uri.h" @@ -74,7 +76,7 @@ static napi_value FileAccessHelperConstructor(napi_env env, napi_callback_info i return nullptr; } g_fileAccessHelperList.emplace_back(fileAccessHelper); - + auto finalize = [](napi_env env, void *data, void *hint) { FileAccessHelper *objectInfo = static_cast(data); g_fileAccessHelperList.remove_if([objectInfo](const std::shared_ptr &fileAccessHelper) { @@ -155,6 +157,8 @@ napi_value FileAccessHelperInit(napi_env env, napi_value exports) DECLARE_NAPI_FUNCTION("rename", NAPI_Rename), DECLARE_NAPI_FUNCTION("listFile", NAPI_ListFile), DECLARE_NAPI_FUNCTION("getRoots", NAPI_GetRoots), + DECLARE_NAPI_FUNCTION("on", NAPI_On), + DECLARE_NAPI_FUNCTION("off", NAPI_Off) }; napi_value cons = nullptr; NAPI_CALL(env, @@ -599,5 +603,59 @@ napi_value NAPI_GetRoots(napi_env env, napi_callback_info info) } return NVal::CreateUndefined(env).val_; } -} // namespace AppExecFwk + +napi_value NAPI_On(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::ONE)) { + NError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + FileAccessHelper *fileAccessHelper = GetFileAccessHelper(env, funcArg.GetThisVar()); + if (fileAccessHelper == nullptr) { + NError(EINVAL).ThrowErr(env, "Get FileAccessHelper fail"); + return nullptr; + } + + napi_value napiCallback = funcArg[NARG_POS::FIRST]; + if (!NVal(env, napiCallback).TypeIs(napi_function)) { + NError(EINVAL).ThrowErr(env, "Argument must be function"); + return nullptr; + } + + std::shared_ptr callback = std::make_shared(env, napiCallback); + if (callback == nullptr) { + NError(EINVAL).ThrowErr(env, "new NapiNotifyCallback fail."); + return nullptr; + } + + if (fileAccessHelper->On(callback) != ERR_OK) { + NError(EINVAL).ThrowErr(env, "FileAccessHelper::On fail."); + return nullptr; + } + return NVal::CreateUndefined(env).val_; +} + +napi_value NAPI_Off(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO, NARG_CNT::ZERO)) { + NError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + FileAccessHelper *fileAccessHelper = GetFileAccessHelper(env, funcArg.GetThisVar()); + if (fileAccessHelper == nullptr) { + NError(EINVAL).ThrowErr(env, "Get FileAccessHelper fail"); + return nullptr; + } + + if (fileAccessHelper->Off() != ERR_OK) { + NError(EINVAL).ThrowErr(env, "FileAccessHelper::Off fail."); + return nullptr; + } + return NVal::CreateUndefined(env).val_; +} +} // namespace FileAccessFwk } // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/napi/file_access_module/napi_fileaccess_helper.h b/interfaces/kits/napi/file_access_module/napi_fileaccess_helper.h index 5f3836ce..6b05abda 100644 --- a/interfaces/kits/napi/file_access_module/napi_fileaccess_helper.h +++ b/interfaces/kits/napi/file_access_module/napi_fileaccess_helper.h @@ -32,6 +32,8 @@ namespace FileAccessFwk { napi_value NAPI_Rename(napi_env env, napi_callback_info info); napi_value NAPI_ListFile(napi_env env, napi_callback_info info); napi_value NAPI_GetRoots(napi_env env, napi_callback_info info); + napi_value NAPI_On(napi_env env, napi_callback_info info); + napi_value NAPI_Off(napi_env env, napi_callback_info info); } } // namespace FileAccessFwk #endif // FILE_ACCESS_NAPI_H \ No newline at end of file diff --git a/interfaces/kits/napi/file_access_module/napi_notify_callback.cpp b/interfaces/kits/napi/file_access_module/napi_notify_callback.cpp new file mode 100644 index 00000000..ec7ea62b --- /dev/null +++ b/interfaces/kits/napi/file_access_module/napi_notify_callback.cpp @@ -0,0 +1,90 @@ +/* + * 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_notify_callback.h" + +#include +#include + +namespace OHOS { +namespace FileAccessFwk { +namespace { + const int ARGS_TWO = 2; +} +NapiNotifyCallback::NapiNotifyCallback(napi_env env, napi_value callback) + : env_(env) +{ + napi_create_reference(env, callback, 1, &callback_); + napi_get_uv_event_loop(env, &loop_); +} + +NapiNotifyCallback::~NapiNotifyCallback() +{ + napi_delete_reference(env_, callback_); +} + +void NapiNotifyCallback::OnNotify(const Uri &uri, const NotifyType notifyType) +{ + std::shared_ptr work = std::make_shared(); + if (work == nullptr) { + HILOG_ERROR("failed to new uv_work_t"); + return; + } + CallbackParam* param = new CallbackParam(this, uri.ToString(), notifyType); + if (param == nullptr) { + HILOG_ERROR("failed to new param"); + return; + } + work->data = std::move(param); + int ret = uv_queue_work(loop_, work.get(), + [](uv_work_t *work) {}, + [](uv_work_t *work, int status) { + std::shared_ptr param; + param.reset(std::move(reinterpret_cast(work->data))); + + napi_value uri = nullptr; + napi_status ret = napi_create_string_utf8(param->callback_->env_, param->uri_.c_str(), + param->uri_.length(), &uri); + if (ret != napi_ok) { + HILOG_ERROR("failed to create param Uri"); + return; + } + + napi_value notifyType = nullptr; + ret = napi_create_int32(param->callback_->env_, (int32_t)(param->notifyType_), ¬ifyType); + if (ret != napi_ok) { + HILOG_ERROR("failed to create param NotifyType"); + return; + } + napi_value callback = nullptr; + napi_value args[ARGS_TWO] = {uri, notifyType}; + napi_get_reference_value(param->callback_->env_, param->callback_->callback_, &callback); + napi_value global = nullptr; + napi_get_global(param->callback_->env_, &global); + napi_value result = nullptr; + ret = napi_call_function(param->callback_->env_, global, callback, ARGS_TWO, args, &result); + if (ret != napi_ok) { + HILOG_ERROR("notify failed status:%{public}d.", ret); + } + }); + if (ret != 0) { + if (work->data != nullptr) { + delete (CallbackParam *)(work->data); + work->data = nullptr; + } + } +} +} // namespace FileAccessFwk +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/napi/file_access_module/napi_notify_callback.h b/interfaces/kits/napi/file_access_module/napi_notify_callback.h new file mode 100644 index 00000000..f2e2d741 --- /dev/null +++ b/interfaces/kits/napi/file_access_module/napi_notify_callback.h @@ -0,0 +1,50 @@ +/* + * 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_NOTIFY_CALLBACK_H__ +#define __NAPI_NOTIFY_CALLBACK_H__ + +#include "hilog_wrapper.h" +#include "inotify_callback.h" +#include "napi/native_common.h" +#include "napi/native_node_api.h" +#include "napi/native_api.h" +#include "uri.h" + +namespace OHOS { +namespace FileAccessFwk { +class NapiNotifyCallback : public INotifyCallback { +public: + NapiNotifyCallback(napi_env env, napi_value callback); + virtual ~NapiNotifyCallback(); + void OnNotify(const Uri &uri, const NotifyType notifyType) override; + + struct CallbackParam { + NapiNotifyCallback *callback_; + std::string uri_; + NotifyType notifyType_; + CallbackParam(NapiNotifyCallback *callback, std::string uri, NotifyType notifyType) + : callback_(callback), uri_(uri), notifyType_(notifyType) + { + } + }; +private: + napi_ref callback_ = nullptr; + napi_env env_; + uv_loop_s *loop_ = nullptr; +}; +} // FileAccessFwk +} // OHOS +#endif // __NAPI_NOTIFY_CALLBACK_H__ \ No newline at end of file diff --git a/services/file_extension_hap/entry/src/main/ets/FileExtensionAbility/FileExtensionAbility.ts b/services/file_extension_hap/entry/src/main/ets/FileExtensionAbility/FileExtensionAbility.ts index cc1f3497..a85bc2da 100644 --- a/services/file_extension_hap/entry/src/main/ets/FileExtensionAbility/FileExtensionAbility.ts +++ b/services/file_extension_hap/entry/src/main/ets/FileExtensionAbility/FileExtensionAbility.ts @@ -14,32 +14,46 @@ */ import Extension from '@ohos.application.FileAccessExtensionAbility' import fileio from '@ohos.fileio' -import { init, delVolumeInfo, getVolumeInfoList } from './VolumeManager' +import { init, findVolumeInfo, delVolumeInfo, getVolumeInfoList, path2uri } from './VolumeManager' import { onReceiveEvent } from './Subcriber' import fileExtensionInfo from "@ohos.fileExtensionInfo" import hilog from '@ohos.hilog' import process from '@ohos.process'; const FLAG = fileExtensionInfo.FLAG; +const NotifyType = fileExtensionInfo.NotifyType; const BUNDLE_NAME = 'com.ohos.UserFile.ExternalFileManager'; const DEFAULT_MODE = 0o666; const CREATE_FILE_FLAGS = 0o100; const FILE_ACCESS = 'fileAccess://'; const DOMAIN_CODE = 0x0001; const TAG = 'js_server'; +let callbackFun = null; export default class FileExtAbility extends Extension { onCreate(want) { init(); onReceiveEvent(function (data) { if (data.event == 'usual.event.data.VOLUME_MOUNTED') { + let uri = path2uri('', data.parameters.path); + callbackFun(uri, NotifyType.DEVICE_ONLINE); process.exit(0); } else { + let uri = ''; + let volumeInfo = findVolumeInfo(data.parameters.id); + if (volumeInfo) { + uri = volumeInfo.uri; + } + callbackFun(uri, NotifyType.DEVICE_OFFLINE); delVolumeInfo(data.parameters.id); } }); } + registerCallback(callback) { + callbackFun = callback; + } + checkUri(uri) { if(uri.indexOf(FILE_ACCESS) == 0) { uri = uri.replace(FILE_ACCESS, ''); diff --git a/services/file_extension_hap/entry/src/main/ets/FileExtensionAbility/VolumeManager.ts b/services/file_extension_hap/entry/src/main/ets/FileExtensionAbility/VolumeManager.ts index 63c5bf91..2944442c 100644 --- a/services/file_extension_hap/entry/src/main/ets/FileExtensionAbility/VolumeManager.ts +++ b/services/file_extension_hap/entry/src/main/ets/FileExtensionAbility/VolumeManager.ts @@ -49,6 +49,10 @@ function path2uri(id, path) { return `fileAccess://${id}${path}`; } +function findVolumeInfo(volumeId) { + return globalThis.volumeInfoList.find((volume) => volume.volumeId == volumeId); +} + function delVolumeInfo(volumeId) { globalThis.volumeInfoList = globalThis.volumeInfoList.filter((volume) => volume.volumeId !== volumeId); } @@ -57,4 +61,4 @@ function getVolumeInfoList() { return globalThis.volumeInfoList; } -export { init, addVolumeInfo, delVolumeInfo, getVolumeInfoList, path2uri } \ No newline at end of file +export { init, addVolumeInfo, findVolumeInfo, delVolumeInfo, getVolumeInfoList, path2uri } \ No newline at end of file diff --git a/utils/file_access_framework_errno.h b/utils/file_access_framework_errno.h index 6f8bfd17..fd941cff 100644 --- a/utils/file_access_framework_errno.h +++ b/utils/file_access_framework_errno.h @@ -21,15 +21,22 @@ 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_PARCEL_ERROR, // parcel write/read fail ERR_PERMISSION_DENIED, // no permission ERR_INVALID_FD, // invalid fd ERR_INVALID_URI, // invalid uri ERR_URI_CHECK, // check uri head fail + ERR_INVALID_NOTIFY, // invalid notify + ERR_REMOVE_NOTIFY_FAIL, // remove notify fail + ERR_NOTIFY_NOT_EXIST, // the notify is not exist + ERR_NOTIFY_EXIST, // the notify is exist ERR_FILEIO_FAIL, // fileio fail ERR_INVALID_PARAM // invalid parameter }; -- Gitee From 70a5f2a65380cd3c91c3d0a981a4b2ba13299f90 Mon Sep 17 00:00:00 2001 From: linjun9528 Date: Thu, 14 Jul 2022 11:04:49 +0800 Subject: [PATCH 2/3] add notify code Signed-off-by: linjun9528 --- frameworks/innerkits/file_access/BUILD.gn | 6 +++--- .../innerkits/file_access/include/ifile_access_ext_base.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/frameworks/innerkits/file_access/BUILD.gn b/frameworks/innerkits/file_access/BUILD.gn index 01943788..eb3bc52b 100644 --- a/frameworks/innerkits/file_access/BUILD.gn +++ b/frameworks/innerkits/file_access/BUILD.gn @@ -57,12 +57,12 @@ ohos_shared_library("file_access_extension_ability_kit") { "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", "src/notify/file_access_notify_client.cpp", "src/notify/file_access_notify_manager.cpp", - "src/notify/file_access_notify_stub.cpp", "src/notify/file_access_notify_proxy.cpp", - "src/js_file_access_ext_ability.cpp", - "src/napi_common_fileaccess.cpp", + "src/notify/file_access_notify_stub.cpp", ] configs = [ ":ability_config" ] public_configs = [ diff --git a/frameworks/innerkits/file_access/include/ifile_access_ext_base.h b/frameworks/innerkits/file_access/include/ifile_access_ext_base.h index e24d01b2..e9db9f4f 100644 --- a/frameworks/innerkits/file_access/include/ifile_access_ext_base.h +++ b/frameworks/innerkits/file_access/include/ifile_access_ext_base.h @@ -40,7 +40,7 @@ public: CMD_MOVE, CMD_RENAME, CMD_LIST_FILE, - CMD_GET_ROOTS + CMD_GET_ROOTS, CMD_REGISTER_NOTIFY, CMD_UNREGISTER_NOTIFY, }; -- Gitee From eab2f24908c1eaa8937242bd34cc9447e748486b Mon Sep 17 00:00:00 2001 From: linjun9528 Date: Thu, 14 Jul 2022 11:25:05 +0800 Subject: [PATCH 3/3] fix codex Signed-off-by: linjun9528 --- .../innerkits/file_access/src/js_file_access_ext_ability.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 639bde50..4d4802e3 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 @@ -90,7 +90,7 @@ void JsFileAccessExtAbility::Init(const std::shared_ptr &rec NativeValue* JsFileAccessExtAbility::FuncCallback(NativeEngine* engine, NativeCallbackInfo* info) { if (engine == nullptr || info == nullptr) { - HILOG_INFO("%invalid param."); + HILOG_INFO("invalid param."); return engine->CreateUndefined(); } if (info->argc != ARGC_TWO || info->argv[ARGC_ZERO] == nullptr || info->argv[ARGC_ONE] == nullptr) { -- Gitee