diff --git a/interfaces/kits/js/BUILD.gn b/interfaces/kits/js/BUILD.gn index 4a67419f1e2341ca5d763664d10ce895e60c4c66..b95321ad7f280b59dfdc1fc9efaf7202591dea0b 100644 --- a/interfaces/kits/js/BUILD.gn +++ b/interfaces/kits/js/BUILD.gn @@ -52,7 +52,6 @@ ohos_shared_library("fileio") { "src/mod_fileio/class_stat/stat_n_exporter.cpp", "src/mod_fileio/class_stream/flush.cpp", "src/mod_fileio/class_stream/stream_n_exporter.cpp", - "src/mod_fileio/class_watcher/watcher_n_exporter.cpp", "src/mod_fileio/common_func.cpp", "src/mod_fileio/module.cpp", "src/mod_fileio/properties/chmod.cpp", @@ -86,7 +85,6 @@ ohos_shared_library("fileio") { "src/mod_fileio/properties/stat.cpp", "src/mod_fileio/properties/symlink.cpp", "src/mod_fileio/properties/truncate.cpp", - "src/mod_fileio/properties/watcher.cpp", ] deps = [ @@ -117,6 +115,8 @@ ohos_shared_library("fs") { "src/common/file_helper/fd_guard.cpp", "src/mod_fs/class_file/file_n_exporter.cpp", "src/mod_fs/class_stat/stat_n_exporter.cpp", + "src/mod_fs/class_watcher/file_watcher.cpp", + "src/mod_fs/class_watcher/watcher_n_exporter.cpp", "src/mod_fs/common_func.cpp", "src/mod_fs/module.cpp", "src/mod_fs/properties/lstat.cpp", @@ -125,6 +125,7 @@ ohos_shared_library("fs") { "src/mod_fs/properties/stat.cpp", "src/mod_fs/properties/symlink.cpp", "src/mod_fs/properties/truncate.cpp", + "src/mod_fs/properties/watcher.cpp", ] deps = [ diff --git a/interfaces/kits/js/src/common/napi/n_val.cpp b/interfaces/kits/js/src/common/napi/n_val.cpp index d05ff522128b7fa64a031d2d59350c3e76a4626e..41ccc75a2198d211fd0d7d551acec7b827d5c78d 100644 --- a/interfaces/kits/js/src/common/napi/n_val.cpp +++ b/interfaces/kits/js/src/common/napi/n_val.cpp @@ -131,6 +131,13 @@ tuple NVal::ToDouble() const return make_tuple(status == napi_ok, res); } +tuple NVal::ToUint32() const +{ + uint32_t res = 0; + napi_status status = napi_get_value_uint32(env_, val_, &res); + return make_tuple(status == napi_ok, res); +} + tuple NVal::ToUint64() const { uint64_t res = 0; @@ -154,6 +161,21 @@ tuple, uint32_t> NVal::ToStringArray() return make_tuple(status == napi_ok, stringArray, size); } +tuple, uint32_t> NVal::ToUint32Array() +{ + napi_status status; + uint32_t size; + status = napi_get_array_length(env_, val_, &size); + vector uint32Array; + napi_value result; + for (uint32_t i = 0; i < size; i++) { + status = napi_get_element(env_, val_, i, &result); + auto [succ, uint32] = NVal(env_, result).ToUint32(); + uint32Array.push_back(uint32); + } + return make_tuple(status == napi_ok, uint32Array, size); +} + tuple NVal::ToArraybuffer() const { void *buf = nullptr; @@ -259,6 +281,13 @@ NVal NVal::CreateInt32(napi_env env, int32_t val) return { env, res }; } +NVal NVal::CreateUint32(napi_env env, int32_t val) +{ + napi_value res = nullptr; + napi_create_uint32(env, val, &res); + return {env, res}; +} + NVal NVal::CreateObject(napi_env env) { napi_value res = nullptr; diff --git a/interfaces/kits/js/src/common/napi/n_val.h b/interfaces/kits/js/src/common/napi/n_val.h index 8fd57dc3747516397993b63abbfa7d1ce6969ed2..21fa6c1aa567c74562c2ac22822a250d9b6892b4 100644 --- a/interfaces/kits/js/src/common/napi/n_val.h +++ b/interfaces/kits/js/src/common/napi/n_val.h @@ -47,14 +47,17 @@ public: std::tuple ToArraybuffer() const; std::tuple ToTypedArray() const; std::tuple, uint32_t> ToStringArray(); + std::tuple, uint32_t> ToUint32Array(); std::tuple ToUint64() const; + std::tuple ToUint32() const; std::tuple ToDouble() const; - + /* Static helpers to create js objects */ static NVal CreateUndefined(napi_env env); static NVal CreateBigInt64(napi_env env, int64_t val); static NVal CreateInt64(napi_env env, int64_t val); static NVal CreateInt32(napi_env env, int32_t val); + static NVal CreateUint32(napi_env env, int32_t val); static NVal CreateObject(napi_env env); static NVal CreateBool(napi_env env, bool val); static NVal CreateUTF8String(napi_env env, std::string str); diff --git a/interfaces/kits/js/src/common/uni_error.h b/interfaces/kits/js/src/common/uni_error.h index b9d2b7a303dff27f623747fef517cbc47a2d07b2..e7b47bb79f3c4a5798deec19ebf83978cece43d9 100644 --- a/interfaces/kits/js/src/common/uni_error.h +++ b/interfaces/kits/js/src/common/uni_error.h @@ -81,7 +81,8 @@ enum ErrCodeSuffix { E_BADFD, E_RESTART, E_DQUOT, - E_UKERR + E_UKERR, + E_WATHCER_INIT }; const std::unordered_map> errCodeTable { @@ -126,6 +127,7 @@ const std::unordered_map> errCodeTable { { EBADFD, { FILEIO_SYS_CAP_TAG + E_BADFD, "File descriptor in bad state" } }, { ERESTART, { FILEIO_SYS_CAP_TAG + E_RESTART, "Interrupted system call should be restarted" } }, { EDQUOT, { FILEIO_SYS_CAP_TAG + E_DQUOT, "Quota exceeded" } }, + { FILEIO_SYS_CAP_TAG + E_WATHCER_INIT, { FILEIO_SYS_CAP_TAG + E_WATHCER_INIT, "Watcher init error" } }, { -1, { FILEIO_SYS_CAP_TAG + E_UKERR, "Unknown error" } } }; diff --git a/interfaces/kits/js/src/mod_fileio/module.cpp b/interfaces/kits/js/src/mod_fileio/module.cpp index b26592acb850f6dab3a0cae722cf4d1e66adcd5d..f45251a6666578d86161b38931c0b9392c4fd6cc 100644 --- a/interfaces/kits/js/src/mod_fileio/module.cpp +++ b/interfaces/kits/js/src/mod_fileio/module.cpp @@ -23,7 +23,6 @@ #include "class_randomaccessfile/randomaccessfile_n_exporter.h" #include "class_stat/stat_n_exporter.h" #include "class_stream/stream_n_exporter.h" -#include "class_watcher/watcher_n_exporter.h" #include "properties/prop_n_exporter.h" using namespace std; @@ -40,7 +39,6 @@ static napi_value Export(napi_env env, napi_value exports) products.emplace_back(make_unique(env, exports)); products.emplace_back(make_unique(env, exports)); products.emplace_back(make_unique(env, exports)); - products.emplace_back(make_unique(env, exports)); products.emplace_back(make_unique(env, exports)); for (auto &&product : products) { diff --git a/interfaces/kits/js/src/mod_fileio/properties/prop_n_exporter.cpp b/interfaces/kits/js/src/mod_fileio/properties/prop_n_exporter.cpp index a7a1acbac088698fb66ed9578bc278734cd3a172..6f7518610e45b810f5c8f6ef7ce246baab953d19 100644 --- a/interfaces/kits/js/src/mod_fileio/properties/prop_n_exporter.cpp +++ b/interfaces/kits/js/src/mod_fileio/properties/prop_n_exporter.cpp @@ -20,7 +20,8 @@ #include #include #include - +#include +#include #include "../common_func.h" #include "chmod.h" #include "chown.h" @@ -52,7 +53,6 @@ #include "stat.h" #include "symlink.h" #include "truncate.h" -#include "watcher.h" namespace OHOS { namespace DistributedFS { @@ -687,7 +687,6 @@ bool PropNExporter::Export() NVal::DeclareNapiFunction("createRandomAccessFileSync", CreateRandomAccessFile::Sync), NVal::DeclareNapiFunction("createStream", CreateStream::Async), NVal::DeclareNapiFunction("createStreamSync", CreateStream::Sync), - NVal::DeclareNapiFunction("createWatcher", Watcher::CreateWatcher), NVal::DeclareNapiFunction("fchmod", Fchmod::Async), NVal::DeclareNapiFunction("fchmodSync", Fchmod::Sync), NVal::DeclareNapiFunction("fchown", Fchown::Async), diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/file_watcher.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/file_watcher.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d6b0f8f69df3cf94d08c4b591fdb39307d5c594a --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_watcher/file_watcher.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2021 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_watcher.h" +#include +#include +#include "filemgmt_libhilog.h" +#include "uv.h" +namespace OHOS::FileManagement::ModuleFileIO { +using namespace OHOS::FileManagement::LibN; +const int BUF_SIZE = 1024; +FileWatcher::FileWatcher() {} + +FileWatcher::~FileWatcher() {} + +bool FileWatcher::InitNotify(int &fd) +{ + fd = inotify_init(); + if (fd == -1) { + HILOGE("FileWatcher InitNotify fail errCode:%{public}d", errno); + return false; + } + return true; +} + +bool FileWatcher::StartNotify(std::shared_ptr &arg) +{ + int wd = 0; + uint32_t watchEvent = 0; + for (auto event : arg->events) { + watchEvent = watchEvent | event; + } + wd = inotify_add_watch(arg->fd, arg->filename.c_str(), watchEvent); + if(wd == -1) { + HILOGE("FileWatcher StartNotify fail errCode:%{public}d", errno); + return false; + } + arg->wd = wd; + run_ = true; + return true; +} + +bool FileWatcher::StopNotify(std::shared_ptr &arg) +{ + run_ = false; + if (inotify_rm_watch(arg->fd, arg->wd) == -1) { + HILOGE("FileWatcher StopNotify fail errCode:%{public}d", errno); + return false; + } + close(arg->fd); + return true; +} + +void FileWatcher::HandleEvent(std::shared_ptr &arg, + const struct inotify_event *event, + WatcherCallback callback) +{ + if (event->wd == arg->wd) { + for (auto watchEvent : arg->events) { + if (event->mask == watchEvent || watchEvent == IN_ALL_EVENTS) { + std::string filename = arg->filename + "/" + event->name; + HILOGI("FileWatcher HandleEvent fileName:%{public}s, mask:%{public}d", filename.c_str(), event->mask); + callback(arg->env, arg->ref, filename, event->mask); + } + } + } +} + +void FileWatcher::GetNotifyEvent(std::shared_ptr &arg, WatcherCallback callback) +{ + char buf[BUF_SIZE] = {0}; + struct inotify_event *event = nullptr; + while (run_) { + int fd = arg->fd; + fd_set fds; + FD_ZERO(&fds); + FD_SET(fd, &fds); + if (select(fd + 1, &fds, NULL, NULL, NULL) > 0) { + int len, index = 0; + while (((len = read(fd, &buf, sizeof(buf))) < 0) && (errno == EINTR)); + while (index < len) { + event = (struct inotify_event *)(buf + index); + HandleEvent(arg, event, callback); + index += sizeof(struct inotify_event) + event->len; + } + } + } +} +} // namespace OHOS::FileManagement::ModuleFileIO \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/file_watcher.h b/interfaces/kits/js/src/mod_fs/class_watcher/file_watcher.h new file mode 100644 index 0000000000000000000000000000000000000000..ae11351bae9c70e937915c721b979bb3ed2bba6a --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_watcher/file_watcher.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2021 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_WATCHER_H +#define FILE_WATCHER_H +#include +#include +#include +#include "watcher_entity.h" +namespace OHOS::FileManagement::ModuleFileIO { +using WatcherCallback = void (*)(napi_env env, napi_ref callback, const std::string &filename, const uint32_t &event); +struct ErrorInfo { + int errCode; + std::string errMsg; +}; + +class FileWatcher { +public: + FileWatcher(); + ~FileWatcher(); + bool InitNotify(int &fd); + bool StartNotify(std::shared_ptr &arg); + bool StopNotify(std::shared_ptr &arg); + void GetNotifyEvent(std::shared_ptr &arg, WatcherCallback callback); + +private: + void HandleEvent(std::shared_ptr &arg, const struct inotify_event *event, WatcherCallback callback); + bool run_; +}; +} // namespace OHOS::FileManagement::ModuleFileIO +#endif diff --git a/interfaces/kits/js/src/mod_fileio/class_watcher/watcher_entity.h b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h similarity index 55% rename from interfaces/kits/js/src/mod_fileio/class_watcher/watcher_entity.h rename to interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h index ce604ee6b042eb0159ba61ad0bd1fd0251c9ebbb..e1189119583a976d7d11fd5cfadd3030d46368ec 100644 --- a/interfaces/kits/js/src/mod_fileio/class_watcher/watcher_entity.h +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h @@ -15,39 +15,23 @@ #ifndef INTERFACES_KITS_JS_SRC_MOD_FILEIO_CLASS_WATCHER_WATCHER_ENTITY_H #define INTERFACES_KITS_JS_SRC_MOD_FILEIO_CLASS_WATCHER_WATCHER_ENTITY_H +#include +#include +#include +#include "filemgmt_libn.h" +namespace OHOS::FileManagement::ModuleFileIO { -#include - -#include "../../common/napi/uni_header.h" - -namespace OHOS { -namespace DistributedFS { -namespace ModuleFileIO { -class WatcherHandleDeleter { -public: - void operator()(uv_fs_event_t *ptr) - { - if (ptr == nullptr) { - return; - } - - uv_fs_event_stop(ptr); - uv_handle_t *handle = reinterpret_cast(ptr); - uv_close(handle, [](uv_handle_t *handle) { delete handle; }); - } -}; - -struct WatcherInforArg { - int events = 0; +struct WatcherInfoArg { + std::string filename; + std::vector events; + int fd; + int wd; napi_env env = nullptr; napi_ref ref = nullptr; }; struct WatcherEntity { - std::unique_ptr data_; - std::unique_ptr fsEventReq_; + std::shared_ptr data_; }; -} // namespace ModuleFileIO -} // namespace DistributedFS -} // namespace OHOS +} // namespace OHOS::FileManagement::ModuleFileIO namespace OHOS #endif diff --git a/interfaces/kits/js/src/mod_fileio/class_watcher/watcher_n_exporter.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_n_exporter.cpp similarity index 41% rename from interfaces/kits/js/src/mod_fileio/class_watcher/watcher_n_exporter.cpp rename to interfaces/kits/js/src/mod_fs/class_watcher/watcher_n_exporter.cpp index 2947b10cb50e5d108cb3d81e27eb5ee9e53f8274..042bfee9af137385384d5d728a5d6dcc1a0f9f40 100644 --- a/interfaces/kits/js/src/mod_fileio/class_watcher/watcher_n_exporter.cpp +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_n_exporter.cpp @@ -19,112 +19,142 @@ #include #include #include - -#include "../../common/log.h" -#include "../../common/napi/n_async/n_async_work_callback.h" -#include "../../common/napi/n_async/n_async_work_promise.h" -#include "../../common/napi/n_class.h" -#include "../../common/napi/n_func_arg.h" -#include "../../common/uni_error.h" +#include "filemgmt_libn.h" +#include "filemgmt_libhilog.h" +#include "../common_func.h" #include "securec.h" -#include "watcher_entity.h" -namespace OHOS { -namespace DistributedFS { -namespace ModuleFileIO { +namespace OHOS::FileManagement::ModuleFileIO { using namespace std; +using namespace OHOS::FileManagement::LibN; +std::shared_ptr WatcherNExporter::watcherPtr_; napi_value WatcherNExporter::Constructor(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); if (!funcArg.InitArgs(NARG_CNT::ZERO)) { - UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); return nullptr; } unique_ptr watcherEntity = make_unique(); if (!NClass::SetEntityFor(env, funcArg.GetThisVar(), move(watcherEntity))) { - UniError(EIO).ThrowErr(env, "INNER BUG. Failed to wrap entity for obj stat"); + NError(EIO).ThrowErr(env, "INNER BUG. Failed to wrap entity for obj stat"); return nullptr; } + watcherPtr_ = make_shared(); return funcArg.GetThisVar(); } -napi_value WatcherNExporter::StopSync(napi_env env, napi_callback_info info) +napi_value WatcherNExporter::Stop(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); if (!funcArg.InitArgs(NARG_CNT::ZERO)) { - UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); return nullptr; } auto watchEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); if (!watchEntity) { - UniError(EINVAL).ThrowErr(env, "get watcherEntity fail"); + NError(EINVAL).ThrowErr(env, "get watcherEntity fail"); return nullptr; } - - watchEntity->fsEventReq_.reset(); + if (!watcherPtr_->StopNotify(watchEntity->data_)) { + NError(errno).ThrowErr(env); + return nullptr; + } + return NVal::CreateUndefined(env).val_; } -napi_value WatcherNExporter::Stop(napi_env env, napi_callback_info info) +napi_value WatcherNExporter::Start(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); - if (!funcArg.InitArgs(NARG_CNT::ZERO, NARG_CNT::ONE)) { - UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + NError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); return nullptr; } auto watchEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); if (!watchEntity) { - UniError(EINVAL).ThrowErr(env, "get watcherEntity fail"); + NError(EINVAL).ThrowErr(env, "get watcherEntity fail"); return nullptr; } + if(!watcherPtr_->StartNotify(watchEntity->data_)) { + NError(errno).ThrowErr(env); + return nullptr; + } - auto cbExec = [watchEntity](napi_env env) -> UniError { - watchEntity->fsEventReq_.reset(); - return UniError(ERRNO_NOERR); + auto cbExec = [watchEntity]() -> NError { + watcherPtr_->GetNotifyEvent(watchEntity->data_, WatcherCallback); + return NError(ERRNO_NOERR); }; - auto cbCompl = [](napi_env env, UniError err) -> NVal { + auto cbCompl = [](napi_env env, NError err) -> NVal { if (err) { - return { env, err.GetNapiErr(env) }; + return {env, err.GetNapiErr(env)}; } - return { NVal::CreateUndefined(env) }; + return {NVal::CreateUndefined(env)}; }; - const string procedureName = "FileIOCreaterWatcher"; + const string procedureName = "FileIOStartWatcher"; NVal thisVar(env, funcArg.GetThisVar()); - if (funcArg.GetArgc() == NARG_CNT::ZERO) { - return NAsyncWorkPromise(env, thisVar).Schedule(procedureName, cbExec, cbCompl).val_; - } else { - NVal cb(env, funcArg[NARG_POS::FIRST]); - return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureName, cbExec, cbCompl).val_; - } + return NAsyncWorkPromise(env, thisVar).Schedule(procedureName, cbExec, cbCompl).val_; +} + +void WatcherNExporter::WatcherCallback(napi_env env, + napi_ref callback, + const std::string &fileName, + const uint32_t &event) +{ + auto callbackContext = make_unique(); + callbackContext->env_ = env; + callbackContext->ref_ = callback; + callbackContext->fileName_ = fileName; + callbackContext->event_ = event; + napi_value resource = nullptr; + napi_create_string_utf8(env, "FileIOCreateWatcher", NAPI_AUTO_LENGTH, &resource); + + napi_create_async_work( + env, nullptr, resource, [](napi_env env, void *data) {}, + [](napi_env env, napi_status status, void *data) { + // JSCallbackData* jsCallbackData = (JSCallbackData*)data; + auto context = static_cast(data); + napi_value jsCallback = nullptr; + napi_get_reference_value(env, context->ref_, &jsCallback); + NVal objn = NVal::CreateObject(env); + objn.AddProp("fileName", NVal::CreateUTF8String(env, context->fileName_).val_); + objn.AddProp("event", NVal::CreateUint32(env, context->event_).val_); + napi_value global = nullptr; + napi_get_global(env, &global); + napi_value jsObj = nullptr; + napi_call_function(env, global, jsCallback, 1, &(objn.val_), &jsObj); + napi_delete_async_work(env, context->work_); + }, + static_cast(callbackContext.get()), &callbackContext->work_); + napi_queue_async_work(env, callbackContext->work_); + callbackContext.release(); } bool WatcherNExporter::Export() { vector props = { + NVal::DeclareNapiFunction("start", Start), NVal::DeclareNapiFunction("stop", Stop), - NVal::DeclareNapiFunction("stopSync", StopSync), }; string className = GetClassName(); - auto [resDefineClass, classValue] = NClass::DefineClass(exports_.env_, - className, - WatcherNExporter::Constructor, - std::move(props)); + auto [resDefineClass, classValue] = + NClass::DefineClass(exports_.env_, className, WatcherNExporter::Constructor, std::move(props)); if (!resDefineClass) { - UniError(EIO).ThrowErr(exports_.env_, "INNER BUG. Failed to define class"); + NError(EIO).ThrowErr(exports_.env_, "INNER BUG. Failed to define class"); return false; } bool succ = NClass::SaveClass(exports_.env_, className, classValue); if (!succ) { - UniError(EIO).ThrowErr(exports_.env_, "INNER BUG. Failed to save class"); + NError(EIO).ThrowErr(exports_.env_, "INNER BUG. Failed to save class"); return false; } @@ -139,6 +169,4 @@ string WatcherNExporter::GetClassName() WatcherNExporter::WatcherNExporter(napi_env env, napi_value exports) : NExporter(env, exports) {} WatcherNExporter::~WatcherNExporter() {} -} // namespace ModuleFileIO -} // namespace DistributedFS -} // namespace OHOS \ No newline at end of file +} // namespace OHOS::FileManagement::ModuleFileIO diff --git a/interfaces/kits/js/src/mod_fileio/class_watcher/watcher_n_exporter.h b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_n_exporter.h similarity index 60% rename from interfaces/kits/js/src/mod_fileio/class_watcher/watcher_n_exporter.h rename to interfaces/kits/js/src/mod_fs/class_watcher/watcher_n_exporter.h index 3d3502b7babfd5d7c3037cb51d1aee7e1ffa845a..b4e05338689e7ee88fe8b2c716397e537d3cb05d 100644 --- a/interfaces/kits/js/src/mod_fileio/class_watcher/watcher_n_exporter.h +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_n_exporter.h @@ -15,27 +15,43 @@ #ifndef INTERFACES_KITS_JS_SRC_MOD_FILEIO_CLASS_WATCHER_WATCHER_N_EXPORTER_H #define INTERFACES_KITS_JS_SRC_MOD_FILEIO_CLASS_WATCHER_WATCHER_N_EXPORTER_H - -#include "../../common/napi/n_exporter.h" - -namespace OHOS { -namespace DistributedFS { -namespace ModuleFileIO { +#include +#include +#include "watcher_entity.h" +#include "file_watcher.h" +#include "filemgmt_libn.h" +namespace OHOS::FileManagement::ModuleFileIO { +using namespace OHOS::FileManagement::LibN; class WatcherNExporter final : public NExporter { public: + class JSCallbackContext { + public: + JSCallbackContext() {} + ~JSCallbackContext() {} + + public: + napi_env env_; + napi_ref ref_; + std::string fileName_; + uint32_t event_; + napi_async_work work_; + }; + inline static const std::string className_ = "Watcher"; bool Export() override; std::string GetClassName() override; static napi_value Constructor(napi_env env, napi_callback_info info); + static napi_value Start(napi_env env, napi_callback_info info); static napi_value Stop(napi_env env, napi_callback_info info); - static napi_value StopSync(napi_env env, napi_callback_info info); + static void WatcherCallback(napi_env env, napi_ref callback, const std::string &fileName, const uint32_t &event); WatcherNExporter(napi_env env, napi_value exports); ~WatcherNExporter() override; + +private: + static std::shared_ptr watcherPtr_; }; -} // namespace ModuleFileIO -} // namespace DistributedFS -} // namespace OHOS -#endif +} // namespace OHOS::FileManagement::ModuleFileIO +#endif \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/module.cpp b/interfaces/kits/js/src/mod_fs/module.cpp index 9360458390cf8afd56fb0a27db98514e9f520889..b4e7e3afbba4f815e54025f5f24e5aeb3cab7291 100644 --- a/interfaces/kits/js/src/mod_fs/module.cpp +++ b/interfaces/kits/js/src/mod_fs/module.cpp @@ -20,6 +20,7 @@ #include "class_file/file_n_exporter.h" #include "class_stat/stat_n_exporter.h" +#include "class_watcher/watcher_n_exporter.h" #include "filemgmt_libhilog.h" #include "properties/prop_n_exporter.h" @@ -35,6 +36,7 @@ static napi_value Export(napi_env env, napi_value exports) products.emplace_back(make_unique(env, exports)); products.emplace_back(make_unique(env, exports)); products.emplace_back(make_unique(env, exports)); + products.emplace_back(make_unique(env, exports)); for (auto &&product : products) { if (!product->Export()) { @@ -50,4 +52,4 @@ static napi_value Export(napi_env env, napi_value exports) NAPI_MODULE(fs, Export) } // namespace ModuleFileIO } // namespace FileManagement -} // namespace OHOS \ No newline at end of file +} // namespace OHOS diff --git a/interfaces/kits/js/src/mod_fs/properties/prop_n_exporter.cpp b/interfaces/kits/js/src/mod_fs/properties/prop_n_exporter.cpp index 62baa52067ffbbf08b400a343c9282244a52a6db..1a47906cdbb1f042291dbbf367b1fa08047ef4e4 100644 --- a/interfaces/kits/js/src/mod_fs/properties/prop_n_exporter.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/prop_n_exporter.cpp @@ -32,7 +32,7 @@ #include "stat.h" #include "symlink.h" #include "truncate.h" - +#include "watcher.h" namespace OHOS { namespace FileManagement { namespace ModuleFileIO { @@ -284,6 +284,7 @@ bool PropNExporter::Export() NVal::DeclareNapiFunction("truncateSync", Truncate::Sync), NVal::DeclareNapiFunction("write", Write), NVal::DeclareNapiFunction("writeSync", WriteSync), + NVal::DeclareNapiFunction("createWatcher", Watcher::CreateWatcher), }); } diff --git a/interfaces/kits/js/src/mod_fileio/properties/watcher.cpp b/interfaces/kits/js/src/mod_fs/properties/watcher.cpp similarity index 43% rename from interfaces/kits/js/src/mod_fileio/properties/watcher.cpp rename to interfaces/kits/js/src/mod_fs/properties/watcher.cpp index b822f9a3c6461034cb62979578c32354e451d672..0115353b5f6b23c83d4e38a5574901658b753c88 100644 --- a/interfaces/kits/js/src/mod_fileio/properties/watcher.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/watcher.cpp @@ -14,93 +14,68 @@ */ #include "watcher.h" - #include #include +#include #include #include - -#include "../../common/napi/n_async/n_ref.h" -#include "../../common/napi/n_class.h" -#include "../../common/napi/n_func_arg.h" -#include "../../common/napi/n_val.h" -#include "../../common/uni_error.h" - +#include "filemgmt_libhilog.h" +#include "../class_watcher/file_watcher.h" #include "../class_watcher/watcher_entity.h" #include "../class_watcher/watcher_n_exporter.h" -namespace OHOS { -namespace DistributedFS { -namespace ModuleFileIO { +namespace OHOS::FileManagement::ModuleFileIO { using namespace std; - -void Watcher::RunCommand(uv_fs_event_t *handle, const char *filename, int events, int status) -{ - WatcherInforArg *information = (WatcherInforArg *)handle->data; - uint32_t eventsFirst { events }; - uint32_t eventsSecond { information->events }; - if (eventsFirst & eventsSecond) { - napi_handle_scope scope = nullptr; - napi_open_handle_scope(information->env, &scope); - napi_value callback = nullptr; - napi_get_reference_value(information->env, information->ref, &callback); - vector argv; - argv.push_back(NVal::CreateInt64(information->env, events).val_); - napi_value global = nullptr; - napi_get_global(information->env, &global); - napi_value tmp = nullptr; - napi_call_function(information->env, global, callback, argv.size(), argv.data(), &tmp); - } -} - +using namespace OHOS::FileManagement::LibN; napi_value Watcher::CreateWatcher(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); if (!funcArg.InitArgs(NARG_CNT::THREE)) { - UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); return nullptr; } auto [succGetPath, filename, unused] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); if (!succGetPath) { - UniError(EINVAL).ThrowErr(env, "Invalid filename"); + NError(EINVAL).ThrowErr(env, "Invalid filename"); return nullptr; } - auto [succGetEvent, event] = NVal(env, funcArg[NARG_POS::SECOND]).ToInt32(); + auto [succGetEvent, events, size] = NVal(env, funcArg[NARG_POS::SECOND]).ToUint32Array(); if (!succGetEvent) { - UniError(EINVAL).ThrowErr(env, "Invalid event"); + NError(EINVAL).ThrowErr(env, "Invalid event"); return nullptr; } - unique_ptr data = make_unique(); - data->events = event; + int fd = 0; + shared_ptr watcherPtr = make_shared(); + if (!watcherPtr->InitNotify(fd)) { + NError(errno).ThrowErr(env); + return nullptr; + } + + shared_ptr data = make_shared(); + data->events = events; data->env = env; + data->filename = string(filename.get()); + data->fd = fd; + NVal val = NVal(env, funcArg[NARG_POS::THIRD]); napi_create_reference(val.env_, val.val_, 1, &(data->ref)); - uv_loop_s *loop = nullptr; - napi_get_uv_event_loop(env, &loop); - unique_ptr fsEventReq(new uv_fs_event_t); - uv_fs_event_init(loop, fsEventReq.get()); - fsEventReq->data = data.get(); - uv_fs_event_start(fsEventReq.get(), RunCommand, filename.get(), UV_FS_EVENT_RECURSIVE); + napi_value objWatcher = NClass::InstantiateClass(env, WatcherNExporter::className_, {}); if (!objWatcher) { - UniError(EINVAL).ThrowErr(env, "objWatcher create failed"); + NError(EINVAL).ThrowErr(env, "objWatcher create failed"); return nullptr; } auto watcherEntity = NClass::GetEntityOf(env, objWatcher); if (!watcherEntity) { - UniError(EINVAL).ThrowErr(env, "watcherEntity get failed"); + NError(EINVAL).ThrowErr(env, "watcherEntity get failed"); return nullptr; } - - watcherEntity->fsEventReq_ = std::move(fsEventReq); - watcherEntity->data_ = std::move(data); + watcherEntity->data_ = data; return objWatcher; } -} // namespace ModuleFileIO -} // namespace DistributedFS -} // namespace OHOS \ No newline at end of file +} // namespace OHOS::FileManagement::ModuleFileIO diff --git a/interfaces/kits/js/src/mod_fileio/properties/watcher.h b/interfaces/kits/js/src/mod_fs/properties/watcher.h similarity index 73% rename from interfaces/kits/js/src/mod_fileio/properties/watcher.h rename to interfaces/kits/js/src/mod_fs/properties/watcher.h index 45c100cb21057e0a0711212df5ec9846985aebaf..22059672c8876b8650ca3fb52a7cdd685147d822 100644 --- a/interfaces/kits/js/src/mod_fileio/properties/watcher.h +++ b/interfaces/kits/js/src/mod_fs/properties/watcher.h @@ -15,21 +15,12 @@ #ifndef INTERFACES_KITS_JS_SRC_MOD_FILEIO_PROPERTIES_WATCHER_H #define INTERFACES_KITS_JS_SRC_MOD_FILEIO_PROPERTIES_WATCHER_H +#include "filemgmt_libn.h" +namespace OHOS::FileManagement::ModuleFileIO { -#include -#include "../../common/napi/n_val.h" - -namespace OHOS { -namespace DistributedFS { -namespace ModuleFileIO { class Watcher final { public: static napi_value CreateWatcher(napi_env env, napi_callback_info info); - -private: - static void RunCommand(uv_fs_event_t *handle, const char *filename, int events, int status); }; -} // namespace ModuleFileIO -} // namespace DistributedFS -} // namespace OHOS +} // namespace OHOS::FileManagement::ModuleFileIO #endif \ No newline at end of file diff --git a/interfaces/test/unittest/BUILD.gn b/interfaces/test/unittest/BUILD.gn index 4351bd3fe2e6e4af186feb7c20c9587bd7ce7540..d74288bc775f9ce176e1d11eb695a0cf875ca358 100644 --- a/interfaces/test/unittest/BUILD.gn +++ b/interfaces/test/unittest/BUILD.gn @@ -13,5 +13,8 @@ group("unittest") { testonly = true - deps = [ "remote_uri:remote_uri_test" ] + deps = [ + "remote_uri:remote_uri_test", + "file_watcher:file_watcher_test" + ] } diff --git a/interfaces/test/unittest/file_watcher/BUILD.gn b/interfaces/test/unittest/file_watcher/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..fdfc920612831f11e676f82d51c2c8879c8d0d41 --- /dev/null +++ b/interfaces/test/unittest/file_watcher/BUILD.gn @@ -0,0 +1,43 @@ +# 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. + +import("//build/test.gni") + +ohos_unittest("file_watcher_test") { + module_out_path = "filemanagement/file_api" + + resource_config_file = "../resource/ohos_test.xml" + + sources = [ "file_watcher_test.cpp" ] + + include_dirs = [ + "include", + "//utils/system/safwk/native/include", + "//commonlibrary/c_utils/base/include", + "//foundation/filemanagement/file_api/interfaces/kits/js/src/common/napi", + "//foundation/filemanagement/file_api/interfaces/kits/js/src/mod_fileio/class_watcher", + "//third_party/libuv/include", + ] + + deps = [ + "//foundation/filemanagement/file_api/interfaces/kits/js:fileio", + "//third_party/googletest:gtest_main", + "//foundation/arkui/napi:ace_napi", + ] + + external_deps = [ + "access_token:libaccesstoken_sdk", + "c_utils:utils", + "ipc:ipc_core", + ] +} diff --git a/interfaces/test/unittest/file_watcher/file_watcher_test.cpp b/interfaces/test/unittest/file_watcher/file_watcher_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0a1db2167ab13fe6841d87ee2b6d7f5d14676af1 --- /dev/null +++ b/interfaces/test/unittest/file_watcher/file_watcher_test.cpp @@ -0,0 +1,380 @@ +/* +* 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_watcher.h" +#include +#include +#include +#include +#include +#include +#include +#include +namespace { + using namespace std; + using namespace OHOS::DistributedFS::ModuleFileIO; + + class FileWatcherTest : public testing::Test { + public: + static void SetUpTestCase(void){}; + static void TearDownTestCase(){}; + void SetUp(){}; + void TearDown(){}; + }; + + + void WatcherCallback(napi_env env, napi_ref callback, const std::string &filename, const uint32_t &event) + { + string path = "/data/data/test2"; + EXPECT_STREQ(path.c_str(), filename.c_str()); + if (event == IN_CLOSE || event == IN_DELETE) { + EXPECT_TRUE(true); + } else { + EXPECT_TRUE(false); + } + } + + void GetEvent(shared_ptr &fileWatcherPtr, std::shared_ptr &arg) + { + fileWatcherPtr->GetNotifyEvent(arg, WatcherCallback); + } + + /** + * @tc.name: Watcher_InitNotify_0000 + * @tc.desc: Test function of InitNotify() interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: AR000HG8M4 + */ + HWTEST_F(FileWatcherTest, Watcher_InitNotify_0000, testing::ext::TestSize.Level1) + { + GTEST_LOG_(INFO) << "FileWatcherTest-begin Watcher_InitNotify_0000"; + int fd = 0; + int error = 0; + + shared_ptr fileWatcherPtr = make_shared(); + bool ret = fileWatcherPtr->InitNotify(fd, error); + + EXPECT_TRUE(fd > 0); + EXPECT_TRUE(error == 0); + EXPECT_TRUE(ret == true); + + GTEST_LOG_(INFO) << "FileWatcherTest-end Watcher_InitNotify_0000"; + } + + /** + * @tc.name: Watcher_StartNotify_0000 + * @tc.desc: Test function of StartNotify() interface for FAIL. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: AR000HG8M4 + */ + HWTEST_F(FileWatcherTest, Watcher_StartNotify_0000, testing::ext::TestSize.Level1) + { + GTEST_LOG_(INFO) << "FileWatcherTest-begin Watcher_StartNotify_0000"; + int error = 0; + std::shared_ptr arg = make_shared(); + shared_ptr fileWatcherPtr = make_shared(); + bool ret = fileWatcherPtr->StartNotify(arg, error); + EXPECT_TRUE(ret == false); + EXPECT_TRUE(error > 0); + + GTEST_LOG_(INFO) << "FileWatcherTest-end Watcher_StartNotify_0000"; + } + + /** + * @tc.name: Watcher_StartNotify_0001 + * @tc.desc: Test function of StartNotify() interface for FAIL. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: AR000HG8M4 + */ + HWTEST_F(FileWatcherTest, Watcher_StartNotify_0001, testing::ext::TestSize.Level1) + { + GTEST_LOG_(INFO) << "FileWatcherTest-begin Watcher_StartNotify_0001"; + int error = 0; + std::shared_ptr arg = make_shared(); + arg->fd = 10; + + shared_ptr fileWatcherPtr = make_shared(); + bool ret = fileWatcherPtr->StartNotify(arg, error); + EXPECT_TRUE(ret == false); + EXPECT_TRUE(error > 0); + + GTEST_LOG_(INFO) << "FileWatcherTest-end Watcher_StartNotify_0001"; + } + + /** + * @tc.name: Watcher_StartNotify_0002 + * @tc.desc: Test function of StartNotify() interface for FAIL. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: AR000HG8M4 + */ + HWTEST_F(FileWatcherTest, Watcher_StartNotify_0002, testing::ext::TestSize.Level1) + { + GTEST_LOG_(INFO) << "FileWatcherTest-begin Watcher_StartNotify_0002"; + int fd = 0; + int error = 0; + bool ret = false; + + shared_ptr fileWatcherPtr = make_shared(); + ret = fileWatcherPtr->InitNotify(fd, error); + EXPECT_TRUE(fd > 0); + EXPECT_TRUE(ret == true); + + std::shared_ptr arg = make_shared(); + arg->fd = fd; + arg->filename = ""; + + ret = fileWatcherPtr->StartNotify(arg, error); + EXPECT_TRUE(ret == false); + EXPECT_TRUE(error > 0); + + GTEST_LOG_(INFO) << "FileWatcherTest-end Watcher_StartNotify_0002"; + } + + /** + * @tc.name: Watcher_StartNotify_0003 + * @tc.desc: Test function of StartNotify() interface for FAIL. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: AR000HG8M4 + */ + HWTEST_F(FileWatcherTest, Watcher_StartNotify_0003, testing::ext::TestSize.Level1) + { + GTEST_LOG_(INFO) << "FileWatcherTest-begin Watcher_StartNotify_0003"; + int fd = 0; + int error = 0; + bool ret = false; + + shared_ptr fileWatcherPtr = make_shared(); + ret = fileWatcherPtr->InitNotify(fd, error); + EXPECT_TRUE(fd > 0); + EXPECT_TRUE(ret == true); + + std::shared_ptr arg = make_shared(); + arg->fd = fd; + arg->filename = "/data/data"; + + ret = fileWatcherPtr->StartNotify(arg, error); + EXPECT_TRUE(ret == false); + EXPECT_TRUE(error > 0); + + GTEST_LOG_(INFO) << "FileWatcherTest-end Watcher_StartNotify_0003"; + } + + /** + * @tc.name: Watcher_StartNotify_0004 + * @tc.desc: Test function of StartNotify() interface for FAIL. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: AR000HG8M4 + */ + HWTEST_F(FileWatcherTest, Watcher_StartNotify_0004, testing::ext::TestSize.Level1) + { + GTEST_LOG_(INFO) << "FileWatcherTest-begin Watcher_StartNotify_0004"; + int fd = 0; + int error = 0; + bool ret = false; + + shared_ptr fileWatcherPtr = make_shared(); + ret = fileWatcherPtr->InitNotify(fd, error); + EXPECT_TRUE(fd > 0); + EXPECT_TRUE(ret == true); + + std::vector events; + events.push_back(0); + + std::shared_ptr arg = make_shared(); + arg->fd = fd; + arg->filename = "/data/data"; + arg->events = events; + + ret = fileWatcherPtr->StartNotify(arg, error); + EXPECT_TRUE(ret == false); + EXPECT_TRUE(error > 0); + + GTEST_LOG_(INFO) << "FileWatcherTest-end Watcher_StartNotify_0004"; + } + + /** + * @tc.name: Watcher_StartNotify_0005 + * @tc.desc: Test function of StartNotify() interface for FAIL. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: AR000HG8M4 + */ + HWTEST_F(FileWatcherTest, Watcher_StartNotify_0005, testing::ext::TestSize.Level1) + { + GTEST_LOG_(INFO) << "FileWatcherTest-begin Watcher_StartNotify_0005"; + int fd = 0; + int error = 0; + bool ret = false; + + shared_ptr fileWatcherPtr = make_shared(); + ret = fileWatcherPtr->InitNotify(fd, error); + EXPECT_TRUE(fd > 0); + EXPECT_TRUE(ret == true); + + std::vector events; + events.push_back(IN_ACCESS); + + std::shared_ptr arg = make_shared(); + arg->fd = fd; + arg->filename = "/data/test"; + arg->events = events; + + ret = fileWatcherPtr->StartNotify(arg, error); + EXPECT_TRUE(ret == false); + EXPECT_TRUE(error > 0); + + GTEST_LOG_(INFO) << "FileWatcherTest-end Watcher_StartNotify_0005"; + } + + /** + * @tc.name: Watcher_StartNotify_0006 + * @tc.desc: Test function of StartNotify() interface for FAIL. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: AR000HG8M4 + */ + HWTEST_F(FileWatcherTest, Watcher_StartNotify_0006, testing::ext::TestSize.Level1) + { + GTEST_LOG_(INFO) << "FileWatcherTest-begin Watcher_StartNotify_0006"; + int fd = 0; + int error = 0; + bool ret = false; + + shared_ptr fileWatcherPtr = make_shared(); + ret = fileWatcherPtr->InitNotify(fd, error); + EXPECT_TRUE(fd > 0); + EXPECT_TRUE(ret == true); + + std::vector events; + events.push_back(IN_ACCESS); + + std::shared_ptr arg = make_shared(); + arg->fd = fd; + arg->filename = "/data/test"; + arg->events = events; + + ret = fileWatcherPtr->StartNotify(arg, error); + EXPECT_TRUE(ret == false); + EXPECT_TRUE(error > 0); + + GTEST_LOG_(INFO) << "FileWatcherTest-end Watcher_StartNotify_0006"; + } + + /** + * @tc.name: Watcher_StartNotify_0007 + * @tc.desc: Test function of StartNotify() interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: AR000HG8M4 + */ + HWTEST_F(FileWatcherTest, Watcher_StartNotify_0007, testing::ext::TestSize.Level1) + { + GTEST_LOG_(INFO) << "FileWatcherTest-begin Watcher_StartNotify_0007"; + int fd = 0; + int error = 0; + bool ret = false; + string filename = "/data/data/test"; + int fileFd = open(filename.c_str(), O_CREAT); + EXPECT_TRUE(fileFd > 0); + + shared_ptr fileWatcherPtr = make_shared(); + ret = fileWatcherPtr->InitNotify(fd, error); + EXPECT_TRUE(fd > 0); + EXPECT_TRUE(ret == true); + + std::vector events; + events.push_back(IN_ACCESS); + + std::shared_ptr arg = make_shared(); + arg->fd = fd; + arg->filename = filename; + arg->events = events; + + ret = fileWatcherPtr->StartNotify(arg, error); + EXPECT_TRUE(ret == true); + EXPECT_TRUE(error == 0); + + ret = fileWatcherPtr->StopNotify(arg, error); + EXPECT_TRUE(ret == true); + GTEST_LOG_(INFO) << "FileWatcherTest-end Watcher_StartNotify_0007"; + } + + /** + * @tc.name: Watcher_GetNotifyEvent_0000 + * @tc.desc: Test function of GetNotifyEvent() interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: AR000HG8M4 + */ + HWTEST_F(FileWatcherTest, Watcher_GetNotifyEvent_0000, testing::ext::TestSize.Level1) + { + GTEST_LOG_(INFO) << "FileWatcherTest-begin Watcher_GetNotifyEvent_0000"; + int fd = 0; + int error = 0; + bool ret = false; + + shared_ptr fileWatcherPtr = make_shared(); + ret = fileWatcherPtr->InitNotify(fd, error); + EXPECT_TRUE(fd > 0); + EXPECT_TRUE(ret == true); + + string filename = "/data/data/test2"; + int fileFd = open(filename.c_str(), O_CREAT); + EXPECT_TRUE(fileFd > 0); + + std::vector events; + events.push_back(IN_CLOSE); + events.push_back(IN_DELETE); + + std::shared_ptr arg = make_shared(); + arg->fd = fd; + arg->filename = filename; + arg->events = events; + + ret = fileWatcherPtr->StartNotify(arg, error); + EXPECT_TRUE(error == 0); + EXPECT_TRUE(ret == true); + + thread t(GetEvent, ref(fileWatcherPtr), ref(arg)); + t.detach(); + + this_thread::sleep_for(chrono::seconds(2)); + int clsoeRet = close(fileFd); + EXPECT_TRUE(clsoeRet == 0); + + this_thread::sleep_for(chrono::seconds(2)); + int removeRet = remove(filename.c_str()); + EXPECT_TRUE(removeRet == 0); + + GTEST_LOG_(INFO) << "FileWatcherTest-end Watcher_GetNotifyEvent_0000"; + } + +} // namespace \ No newline at end of file diff --git a/utils/filemgmt_libn/include/n_val.h b/utils/filemgmt_libn/include/n_val.h index c66b88a56b398ea86bbd5f6285baa0306e43545a..5f40f8fddd1c98021ea1bc6ed70a84e74fd796fa 100644 --- a/utils/filemgmt_libn/include/n_val.h +++ b/utils/filemgmt_libn/include/n_val.h @@ -52,7 +52,9 @@ public: std::tuple ToArraybuffer() const; std::tuple ToTypedArray() const; std::tuple, uint32_t> ToStringArray(); + std::tuple, uint32_t> ToUint32Array(); std::tuple ToUint64() const; + std::tuple ToUint32() const; std::tuple ToDouble() const; /* Static helpers to create js objects */ @@ -60,6 +62,7 @@ public: static NVal CreateBigInt64(napi_env env, int64_t val); static NVal CreateInt64(napi_env env, int64_t val); static NVal CreateInt32(napi_env env, int32_t val); + static NVal CreateUint32(napi_env env, int32_t val); static NVal CreateObject(napi_env env); static NVal CreateBool(napi_env env, bool val); static NVal CreateUTF8String(napi_env env, std::string str); diff --git a/utils/filemgmt_libn/src/n_val.cpp b/utils/filemgmt_libn/src/n_val.cpp index a2d6a591272fc084f06551b6a52fb99350366bd5..8eb6bd48e9f51d3a2c26443f46e72b258d1340e8 100644 --- a/utils/filemgmt_libn/src/n_val.cpp +++ b/utils/filemgmt_libn/src/n_val.cpp @@ -131,6 +131,14 @@ tuple NVal::ToDouble() const return make_tuple(status == napi_ok, res); } +tuple NVal::ToUint32() const +{ + uint32_t res = 0; + napi_status status = napi_get_value_uint32(env_, val_, &res); + return make_tuple(status == napi_ok, res); +} + + tuple NVal::ToUint64() const { uint64_t res = 0; @@ -154,6 +162,21 @@ tuple, uint32_t> NVal::ToStringArray() return make_tuple(status == napi_ok, stringArray, size); } +tuple, uint32_t> NVal::ToUint32Array() +{ + napi_status status; + uint32_t size; + status = napi_get_array_length(env_, val_, &size); + vector uint32Array; + napi_value result; + for (uint32_t i = 0; i < size; i++) { + status = napi_get_element(env_, val_, i, &result); + auto [succ, uint32] = NVal(env_, result).ToUint32(); + uint32Array.push_back(uint32); + } + return make_tuple(status == napi_ok, uint32Array, size); +} + tuple NVal::ToArraybuffer() const { void *buf = nullptr; @@ -258,6 +281,13 @@ NVal NVal::CreateInt32(napi_env env, int32_t val) return {env, res}; } +NVal NVal::CreateUint32(napi_env env, int32_t val) +{ + napi_value res = nullptr; + napi_create_uint32(env, val, &res); + return {env, res}; +} + NVal NVal::CreateObject(napi_env env) { napi_value res = nullptr;