diff --git a/frameworks/innerkits/file_access/BUILD.gn b/frameworks/innerkits/file_access/BUILD.gn index fec4310f0aed959ba2abd1fdee3645887be2f375..18022c1fdab3b2e2a27800e67e7f0ec15953a87b 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", @@ -58,6 +59,10 @@ ohos_shared_library("file_access_extension_ability_kit") { "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_proxy.cpp", + "src/notify/file_access_notify_stub.cpp", ] configs = [ ":ability_config" ] public_configs = [ @@ -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 62bb646cab859cbe9d0583c05f383ac2557f5d03..1bf1ff09090b3b3f86edd95fb613e99ba4f2b3a5 100644 --- a/frameworks/innerkits/file_access/include/file_access_ext_ability.h +++ b/frameworks/innerkits/file_access/include/file_access_ext_ability.h @@ -18,6 +18,7 @@ #include "extension_base.h" #include "file_access_extension_info.h" +#include "file_access_notify_manager.h" namespace OHOS { namespace AbilityRuntime { @@ -48,9 +49,14 @@ 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 NotifyMessage &message); static void SetCreator(const CreatorFunc& creator); private: + bool GetNotifyManager(); static CreatorFunc creator_; + std::unique_ptr notifyManager_; }; } // namespace FileAccessFwk } // namespace OHOS 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 0b1a7b0a614f448beb1f99f48cc6bf61e10725d0..9b17505fe9180207aa9d29d280dbef7c5eb2741a 100644 --- a/frameworks/innerkits/file_access/include/file_access_ext_proxy.h +++ b/frameworks/innerkits/file_access/include/file_access_ext_proxy.h @@ -45,6 +45,8 @@ 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_; }; 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 5766594ddb6890f601bdb8fd364a162f15c44cd5..1ee4303d8883cf02990fa852425c3c0f1f6f79ef 100644 --- a/frameworks/innerkits/file_access/include/file_access_ext_stub.h +++ b/frameworks/innerkits/file_access/include/file_access_ext_stub.h @@ -44,6 +44,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 63ee7b49d5001d05ca58e6b368d1a2f64fc3480d..fb3ba344377496c910cf548580dc00ef9b940448 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 @@ -42,7 +42,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 3acf6103d781ecbfaaf6884df8067d3fb89d994c..0b71d589946456fc560b5e84b189aadec62e17bf 100644 --- a/frameworks/innerkits/file_access/include/file_access_helper.h +++ b/frameworks/innerkits/file_access/include/file_access_helper.h @@ -24,7 +24,9 @@ #include "context.h" #include "file_access_ext_connection.h" #include "file_access_extension_info.h" +#include "file_access_notify_client.h" #include "ifile_access_ext_base.h" +#include "inotify_callback.h" #include "iremote_object.h" #include "refbase.h" #include "uri.h" @@ -53,7 +55,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); @@ -67,6 +70,7 @@ private: sptr fileAccessExtProxy_ = nullptr; 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 554d5bb9ea43edbd42bedf43605b3c98e2db30c6..adf7b77c1590e9b691b5849a22a6e27db75751c2 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 { @@ -38,7 +40,9 @@ public: CMD_MOVE, CMD_RENAME, CMD_LIST_FILE, - CMD_GET_ROOTS + CMD_GET_ROOTS, + CMD_REGISTER_NOTIFY, + CMD_UNREGISTER_NOTIFY }; virtual int OpenFile(const Uri &uri, const int flags) = 0; @@ -50,6 +54,8 @@ public: 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/notify/file_access_notify_client.h b/frameworks/innerkits/file_access/include/notify/file_access_notify_client.h new file mode 100644 index 0000000000000000000000000000000000000000..7ff862138976b572a474cb32a9c4e9deee7aa60d --- /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 Notify(const NotifyMessage &message) 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 0000000000000000000000000000000000000000..031787daf71d42fa5487dd3014c3c911b020308c --- /dev/null +++ b/frameworks/innerkits/file_access/include/notify/file_access_notify_common.h @@ -0,0 +1,83 @@ +/* + * 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 + +#include + +#include "parcel.h" + +namespace OHOS { +namespace FileAccessFwk { +enum NotifyType { + NOTIFY_DEVICE_ONLINE = 1, + NOTIFY_DEVICE_OFFLINE, + NOTIFY_FILE_CREATE, + NOTIFY_FILE_DELETE, + NOTIFY_FILE_MOVE, + NOTIFY_FILE_RENAME +}; + +struct NotifyMessage : public virtual OHOS::Parcelable { +public: + NotifyType notifyType; + std::string srcUri; // source uri when notifyType is (NOTIFY_FILE_MOVE/NOTIFY_FILE_RENAME), other case is "". + std::string dstUri; // destination uri for all notifyType + + NotifyMessage() = default; + NotifyMessage(const NotifyType ¬ifyTypeIn, const std::string &srcUriIn, const std::string &dstUriIn) + : notifyType(notifyTypeIn), srcUri(srcUriIn), dstUri(dstUriIn) + {} + + bool ReadFromParcel(Parcel &parcel) + { + notifyType = (NotifyType)parcel.ReadInt32(); + srcUri = parcel.ReadString(); + dstUri = parcel.ReadString(); + return true; + } + + virtual bool Marshalling(Parcel &parcel) const override + { + if (!parcel.WriteInt32((int32_t)notifyType)) { + return false; + } + if (!parcel.WriteString(srcUri)) { + return false; + } + if (!parcel.WriteString(dstUri)) { + return false; + } + return true; + } + + static NotifyMessage *Unmarshalling(Parcel &parcel) + { + NotifyMessage *message = new (std::nothrow) NotifyMessage(); + if (message == nullptr) { + return nullptr; + } + + if (!message->ReadFromParcel(parcel)) { + delete message; + message = nullptr; + } + return message; + } +}; +} // 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 0000000000000000000000000000000000000000..1f67adcb5c94dc9b8dad11f89e99047b69a41ae1 --- /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 NotifyMessage &message); + +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 0000000000000000000000000000000000000000..fda5f8159e74c9b0225af786b66ce78524baec2e --- /dev/null +++ b/frameworks/innerkits/file_access/include/notify/file_access_notify_proxy.h @@ -0,0 +1,35 @@ +/* + * 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" + +namespace OHOS { +namespace FileAccessFwk { +class FileAccessNotifyProxy : public IRemoteProxy { +public: + explicit FileAccessNotifyProxy(const sptr &impl); + ~FileAccessNotifyProxy() = default; + void Notify(const NotifyMessage &message) 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 0000000000000000000000000000000000000000..eafd2a9ef4c883efd2761e4446d21827f4af01a8 --- /dev/null +++ b/frameworks/innerkits/file_access/include/notify/file_access_notify_stub.h @@ -0,0 +1,31 @@ +/* + * 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" + +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 0000000000000000000000000000000000000000..d019865979b3d4c182ae6bd848c5f7e4ae7180fc --- /dev/null +++ b/frameworks/innerkits/file_access/include/notify/ifile_access_notify.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 I_FILE_ACCESS_NOTIFY_H +#define I_FILE_ACCESS_NOTIFY_H + +#include "file_access_notify_common.h" +#include "iremote_broker.h" + +namespace OHOS { +namespace FileAccessFwk { +class IFileAccessNotify : public IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.FileAccessFwk.IFileAccessNotify"); + + enum { + CMD_NOTIFY = 1, + }; + + virtual void Notify(const NotifyMessage &message) = 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 0000000000000000000000000000000000000000..3ee43687271d799267387d9360b8a997d8bdcf43 --- /dev/null +++ b/frameworks/innerkits/file_access/include/notify/inotify_callback.h @@ -0,0 +1,29 @@ +/* + * 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" + +namespace OHOS { +namespace FileAccessFwk { +class INotifyCallback { +public: + virtual void OnNotify(const NotifyMessage &message) = 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 3aee053a26513d9a7aa8113c3160186f7ed27f6f..cc9c3ceb31403eaf0b9daf860331db999b75aa03 100644 --- a/frameworks/innerkits/file_access/src/file_access_ext_ability.cpp +++ b/frameworks/innerkits/file_access/src/file_access_ext_ability.cpp @@ -101,5 +101,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 NotifyMessage& message) +{ + if (!GetNotifyManager()) { + HILOG_ERROR("GetNotifyManager fail."); + return ERR_ERROR; + } + int ret = notifyManager_->Notify(message); + 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 c230661fe7477739d57ed667f4f11de688e3c51d..80eeb484e92dec6205862bd38f0c0b0dd9ec926a 100644 --- a/frameworks/innerkits/file_access/src/file_access_ext_proxy.cpp +++ b/frameworks/innerkits/file_access/src/file_access_ext_proxy.cpp @@ -398,5 +398,59 @@ 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; + } + HILOG_INFO("%{public}s, called end", __func__); + 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; + } + HILOG_INFO("%{public}s, called end", __func__); + 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 dcf26327ca3fb3c18953fc888c95e0cc3cf6b91c..0953eb24b5f98d9ec9861a1788842ebc0b13a7eb 100644 --- a/frameworks/innerkits/file_access/src/file_access_ext_stub.cpp +++ b/frameworks/innerkits/file_access/src/file_access_ext_stub.cpp @@ -48,6 +48,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() @@ -398,5 +400,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 cf383453e9952b7eaa091e39e7647a3879e452ba..22e7e133f8b1adfbae3c53ea5f9fc34a45bb6f28 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 @@ -145,5 +145,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 958a1fd1bc42a7fb5fcdf7d0fdfcd1748ebda7d8..c5e620ec17f8bee78c2001896a9a9c5c99d530dc 100644 --- a/frameworks/innerkits/file_access/src/file_access_helper.cpp +++ b/frameworks/innerkits/file_access/src/file_access_helper.cpp @@ -272,11 +272,52 @@ std::vector FileAccessHelper::GetRoots() return results; } -void FileAccessDeathRecipient::OnRemoteDied(const wptr &remote) +int FileAccessHelper::On(std::shared_ptr &callback) { - if (handler_) { - handler_(remote); + if (callback == nullptr) { + HILOG_ERROR("failed with invalid callback"); + return ERR_ERROR; + } + if (notifyClient_ != nullptr) { + HILOG_INFO("notifyClient registered yet."); + int ret = fileAccessExtProxy_->UnregisterNotify(notifyClient_); + if (ret != ERR_OK) { + HILOG_INFO("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; + } + auto 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; + } + auto ret = fileAccessExtProxy_->UnregisterNotify(notifyClient_); + if (ret != ERR_OK) { + HILOG_ERROR("fileAccessExtProxy_ unregisterNotify fail"); } + notifyClient_.clear(); + return ret; } FileAccessDeathRecipient::FileAccessDeathRecipient(RemoteDiedHandler handler) : handler_(handler) @@ -286,5 +327,12 @@ FileAccessDeathRecipient::FileAccessDeathRecipient(RemoteDiedHandler handler) : FileAccessDeathRecipient::~FileAccessDeathRecipient() { } + +void FileAccessDeathRecipient::OnRemoteDied(const wptr &remote) +{ + if (handler_ != nullptr) { + handler_(remote); + } +} } // namespace FileAccessFwk } // namespace OHOS \ No newline at end of file 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 0000000000000000000000000000000000000000..58b12f8b98176442b9416efc2189b8c3394a8fa0 --- /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::Notify(const NotifyMessage &message) +{ + if (notifyCallback_ != nullptr) { + notifyCallback_->OnNotify(message); + } +} +} // 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 0000000000000000000000000000000000000000..6da5f90bf89ab5dde6edcf13d902a1b16d66a8f1 --- /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 NotifyMessage& message) +{ + std::lock_guard lock(notifyMapMutex_); + for (auto iter = notifyMap_.begin(); iter != notifyMap_.end(); iter++) { + if (iter->first != nullptr) { + iter->first->Notify(message); + } + } + 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_ != nullptr) { + 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 0000000000000000000000000000000000000000..c09900f5cdbaea8752b6e8e3e7e2136e3ab57f70 --- /dev/null +++ b/frameworks/innerkits/file_access/src/notify/file_access_notify_proxy.cpp @@ -0,0 +1,46 @@ +/* + * 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::Notify(const NotifyMessage& message) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(FileAccessNotifyProxy::GetDescriptor())) { + HILOG_ERROR("write descriptor failed"); + return; + } + if (!data.WriteParcelable(&message)) { + HILOG_ERROR("write parcel message failed"); + return; + } + int error = Remote()->SendRequest(CMD_NOTIFY, data, reply, option); + if (error != 0) { + HILOG_ERROR("SendRequest failed, error %{public}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 0000000000000000000000000000000000000000..a1d3e9a17a3988fbd80761c61772d6aa0a6f0654 --- /dev/null +++ b/frameworks/innerkits/file_access/src/notify/file_access_notify_stub.cpp @@ -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. + */ + +#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_NOTIFY: { + std::shared_ptr message(data.ReadParcelable()); + if (message == nullptr) { + HILOG_ERROR("read parcelable message fail"); + return ERR_PARCEL_ERROR; + } + Notify(*message); + return ERR_OK; + } + default: + HILOG_DEBUG("FileAccessNotifyStub::OnRemoteRequest error code:%{public}u", code); + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); + } +} +} // namespace FileAccessFwk +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/napi/common/file_extension_info_napi.cpp b/interfaces/kits/napi/common/file_extension_info_napi.cpp index 4d6901b68a98a7969430f92c59e114b643aa9796..314cd5778ffb4d93476304edbb1d09038b35f773 100644 --- a/interfaces/kits/napi/common/file_extension_info_napi.cpp +++ b/interfaces/kits/napi/common/file_extension_info_napi.cpp @@ -20,6 +20,7 @@ #include #include "file_access_extension_info.h" +#include "file_access_notify_common.h" #include "hilog_wrapper.h" #include "js_native_api.h" #include "napi/native_common.h" @@ -95,6 +96,21 @@ void InitFlag(napi_env env, napi_value exports) napi_set_named_property(env, exports, propertyName, obj); } +void InitNotifyType(napi_env env, napi_value exports) +{ + char propertyName[] = "NotifyType"; + napi_property_descriptor desc[] = { + DECLARE_NAPI_STATIC_PROPERTY("FILE_CREATE", CreateUint32(env, NOTIFY_FILE_CREATE)), + DECLARE_NAPI_STATIC_PROPERTY("FILE_DELETE", CreateUint32(env, NOTIFY_FILE_DELETE)), + DECLARE_NAPI_STATIC_PROPERTY("FILE_MOVE", CreateUint32(env, NOTIFY_FILE_MOVE)), + DECLARE_NAPI_STATIC_PROPERTY("FILE_RENAME", CreateUint32(env, NOTIFY_FILE_RENAME)) + }; + napi_value obj = nullptr; + napi_create_object(env, &obj); + napi_define_properties(env, obj, sizeof(desc) / sizeof(desc[0]), desc); + napi_set_named_property(env, exports, propertyName, obj); +} + void InitFileInfo(napi_env env, napi_value exports) { char className[] = "FileInfo"; diff --git a/interfaces/kits/napi/common/file_extension_info_napi.h b/interfaces/kits/napi/common/file_extension_info_napi.h index 88ed6243b8a70365ed7a9b29e3279be7ba319265..6fc9c0dea8cd2fc80326c873e2f31d4f0a541f23 100644 --- a/interfaces/kits/napi/common/file_extension_info_napi.h +++ b/interfaces/kits/napi/common/file_extension_info_napi.h @@ -21,6 +21,7 @@ namespace OHOS { namespace FileAccessFwk { void InitFlag(napi_env env, napi_value exports); +void InitNotifyType(napi_env env, napi_value exports); void InitDeviceType(napi_env env, napi_value exports); void InitFileInfo(napi_env env, napi_value exports); void InitDeviceInfo(napi_env env, napi_value exports); diff --git a/interfaces/kits/napi/file_access_module/BUILD.gn b/interfaces/kits/napi/file_access_module/BUILD.gn index fd97e1a0cf445599f98b557b7d05c307a9676325..a020039591ffe4953f54e26156d7524d934a5963 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 c2b1e570d96e0b52219871a0fc5290bb9ad80d87..daf02f95a4f379223468d45fefd389d06509c70a 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" @@ -40,6 +42,18 @@ namespace { constexpr uint32_t INITIAL_REFCOUNT = 1; } +std::string NapiValueToStringUtf8(napi_env env, napi_value value) +{ + std::string result = ""; + return UnwrapStringFromJS(env, value, result); +} + +int NapiValueToInt32Utf8(napi_env env, napi_value value) +{ + int result = ERR_OK; + return UnwrapInt32FromJS(env, value, result); +} + std::list> g_fileAccessHelperList; static napi_value FileAccessHelperConstructor(napi_env env, napi_callback_info info) @@ -155,6 +169,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, @@ -618,5 +634,81 @@ napi_value NAPI_GetRoots(napi_env env, napi_callback_info info) } return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureName, cbExec, cbComplete).val_; } -} // namespace AppExecFwk -} // namespace OHOS \ No newline at end of file + +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::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; + } + auto result = std::make_shared(); + auto cbExec = [result, fileAccessHelper]() -> NError { + *result = fileAccessHelper->Off(); + if (*result != ERR_OK) { + return NError([result]() -> std::tuple { + return { *result, "FileAccessHelper::Off fail." }; + }); + } + return NError(ERRNO_NOERR); + }; + auto cbComplete = [result](napi_env env, NError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } + return NVal::CreateInt32(env, (int32_t)(*result)); + }; + std::string procedureName = "Off"; + if (funcArg.GetArgc() == NARG_CNT::ZERO) { + return NAsyncWorkPromise(env, NVal(env, funcArg.GetThisVar())).Schedule(procedureName, cbExec, cbComplete).val_; + } else { + NVal cb(env, funcArg[NARG_POS::FIRST]); + if (!cb.TypeIs(napi_function)) { + NError(EINVAL).ThrowErr(env, "Argument must be function"); + return nullptr; + } + return NAsyncWorkCallback(env, NVal(env, funcArg.GetThisVar()), cb) + .Schedule(procedureName, cbExec, cbComplete).val_; + } + 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 3436517d95742b8c771268227e308afe1eb93466..4011b2869434e21fa2a2a81a6698688ff7d39d9c 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 // NAPI_FILEACCESS_HELPER_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 0000000000000000000000000000000000000000..a6873e1421bb5ed24ebf4e90afcc934347f306b1 --- /dev/null +++ b/interfaces/kits/napi/file_access_module/napi_notify_callback.cpp @@ -0,0 +1,88 @@ +/* + * 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 "n_val.h" +#include "uv.h" + +using namespace OHOS::FileManagement::LibN; +namespace OHOS { +namespace FileAccessFwk { +namespace { + const int ARGS_ONE = 1; +} + +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 NotifyMessage& message) +{ + std::shared_ptr work = std::make_shared(); + if (work == nullptr) { + HILOG_ERROR("failed to new uv_work_t"); + return; + } + CallbackParam* param = new CallbackParam(this, message); + 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))); + + NVal napiNotifyMessage = NVal::CreateObject(param->callback_->env_); + napiNotifyMessage.AddProp("notifyType", + NVal::CreateInt32(param->callback_->env_, (int32_t)param->message_.notifyType).val_); + napiNotifyMessage.AddProp("srcUri", + NVal::CreateUTF8String(param->callback_->env_, param->message_.srcUri).val_); + napiNotifyMessage.AddProp("dstUri", + NVal::CreateUTF8String(param->callback_->env_, param->message_.dstUri).val_); + + napi_value callback = nullptr; + napi_value args[ARGS_ONE] = {napiNotifyMessage.val_}; + 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; + napi_status ret = napi_call_function(param->callback_->env_, global, callback, ARGS_ONE, 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 0000000000000000000000000000000000000000..52d3491d97b244868d54d0cb2301bc146945883b --- /dev/null +++ b/interfaces/kits/napi/file_access_module/napi_notify_callback.h @@ -0,0 +1,48 @@ +/* + * 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 NotifyMessage &message) override; + +private: + struct CallbackParam { + NapiNotifyCallback *callback_; + NotifyMessage message_; + CallbackParam(NapiNotifyCallback *callback, NotifyMessage message) + : callback_(callback), message_(message) + {} + }; + 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/interfaces/kits/napi/file_access_module/native_fileaccess_module.cpp b/interfaces/kits/napi/file_access_module/native_fileaccess_module.cpp index d125fabf9489cafd83a846cc360631a7ecb43fc0..19127d0ae1f51a51764174a3c2c8e7903fb6ee40 100644 --- a/interfaces/kits/napi/file_access_module/native_fileaccess_module.cpp +++ b/interfaces/kits/napi/file_access_module/native_fileaccess_module.cpp @@ -29,6 +29,7 @@ static napi_value Init(napi_env env, napi_value exports) { FileAccessHelperInit(env, exports); InitFlag(env, exports); + InitNotifyType(env, exports); InitDeviceType(env, exports); InitFileInfo(env, exports); InitDeviceInfo(env, exports); diff --git a/interfaces/kits/napi/file_extension_info_module/BUILD.gn b/interfaces/kits/napi/file_extension_info_module/BUILD.gn index 31a1235c4fb457bd6ec3921fb4cea3f5c9f88617..87fe7ddec74b3ad4953161bb501edefec1de3137 100644 --- a/interfaces/kits/napi/file_extension_info_module/BUILD.gn +++ b/interfaces/kits/napi/file_extension_info_module/BUILD.gn @@ -25,7 +25,8 @@ ohos_shared_library("fileextensioninfo") { ".", "${UFS_BASE_PATH}/interfaces/kits/napi/common", "${FRAMEWORK_PATH}/innerkits/file_access/include", - "//foundation/filemanagement/user_file_service/utils", + "${FRAMEWORK_PATH}/innerkits/file_access/include/notify", + "${UFS_BASE_PATH}/utils", ] sources = [ diff --git a/interfaces/kits/napi/file_extension_info_module/module_export_napi.cpp b/interfaces/kits/napi/file_extension_info_module/module_export_napi.cpp index 3b91fe3b5731eff8450d000ca6e50b865aa38ae6..1f34d44379827f7ecea6830e2d1102d73e3bc9b2 100644 --- a/interfaces/kits/napi/file_extension_info_module/module_export_napi.cpp +++ b/interfaces/kits/napi/file_extension_info_module/module_export_napi.cpp @@ -24,6 +24,7 @@ namespace FileAccessFwk { napi_value FileExtensionInfoExport(napi_env env, napi_value exports) { InitFlag(env, exports); + InitNotifyType(env, exports); InitDeviceType(env, exports); InitFileInfo(env, exports); InitDeviceInfo(env, exports); diff --git a/utils/file_access_framework_errno.h b/utils/file_access_framework_errno.h index e1b17824b71ebfe21257b05e70b96ee8b0472a92..4eee1c8127c1257b8ca0b10cbae87f58d29fb329 100644 --- a/utils/file_access_framework_errno.h +++ b/utils/file_access_framework_errno.h @@ -28,10 +28,15 @@ 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 };