diff --git a/frameworks/innerkits/file_access/include/js_file_ext_ability.h b/frameworks/innerkits/file_access/include/js_file_ext_ability.h index 14ff3942d26b7bac934b453e0b29937abde1c5f1..563d5e679b2c76b966ae1df21c2284ef70b70e8b 100644 --- a/frameworks/innerkits/file_access/include/js_file_ext_ability.h +++ b/frameworks/innerkits/file_access/include/js_file_ext_ability.h @@ -27,6 +27,23 @@ namespace OHOS { namespace FileAccessFwk { using namespace AbilityRuntime; + +struct ThreadLockInfo { + std::mutex fileOperateMutex; + std::condition_variable fileOperateCondition; + bool isReady = false; +}; + +struct CallbackParam { + ThreadLockInfo *lockInfo; + JsRuntime &jsRuntime; + std::shared_ptr jsObj; + const char *funcName; + NativeValue * const *argv; + size_t argc; + NativeValue *result; +}; + class JsFileExtAbility : public FileExtAbility { public: JsFileExtAbility(JsRuntime& jsRuntime); @@ -53,11 +70,12 @@ public: std::vector ListFile(const Uri &sourceFileUri) override; std::vector GetRoots() override; private: + NativeValue* AsnycCallObjectMethod(const char *name, NativeValue * const *argv = nullptr, size_t argc = 0); NativeValue* CallObjectMethod(const char *name, NativeValue * const *argv = nullptr, size_t argc = 0); void GetSrcPath(std::string &srcPath); - JsRuntime& jsRuntime_; - std::unique_ptr jsObj_; + JsRuntime &jsRuntime_; + std::shared_ptr jsObj_; }; } // namespace FileAccessFwk } // namespace OHOS diff --git a/frameworks/innerkits/file_access/src/js_file_ext_ability.cpp b/frameworks/innerkits/file_access/src/js_file_ext_ability.cpp index a85bc33075c6b9d40d7dda039f004c38f0caf350..065f1d850002227ae3b91264aeb87e52771d05ba 100644 --- a/frameworks/innerkits/file_access/src/js_file_ext_ability.cpp +++ b/frameworks/innerkits/file_access/src/js_file_ext_ability.cpp @@ -141,6 +141,71 @@ NativeValue* JsFileExtAbility::CallObjectMethod(const char* name, NativeValue* c return handleScope.Escape(nativeEngine.CallFunction(value, method, argv, argc)); } +static bool DoAsnycWork(CallbackParam *param) +{ + if (param == nullptr || param->jsObj == nullptr) { + HILOG_ERROR("Not found js file object"); + return false; + } + HandleScope handleScope(param->jsRuntime); + NativeValue* value = param->jsObj->Get(); + if (value == nullptr) { + HILOG_ERROR("Failed to get native value object"); + return false; + } + NativeObject* obj = ConvertNativeValueTo(value); + if (obj == nullptr) { + HILOG_ERROR("Failed to get FileExtAbility object"); + return false; + } + NativeValue* method = obj->GetProperty(param->funcName); + if (method == nullptr) { + HILOG_ERROR("Failed to get '%{public}s' from FileExtAbility object", param->funcName); + return false; + } + auto& nativeEngine = param->jsRuntime.GetNativeEngine(); + param->result = handleScope.Escape(nativeEngine.CallFunction(value, method, param->argv, param->argc)); + return true; +} + +NativeValue* JsFileExtAbility::AsnycCallObjectMethod(const char* name, NativeValue* const* argv, size_t argc) +{ + std::shared_ptr lockInfo = std::make_shared(); + std::shared_ptr param = std::make_shared(CallbackParam { + .lockInfo = lockInfo.get(), + .jsRuntime = jsRuntime_, + .jsObj = jsObj_, + .funcName = name, + .argv = argv, + .argc = argc, + .result = nullptr + }); + if (param == nullptr) { + HILOG_ERROR("failed to new param"); + return nullptr; + } + uv_loop_s *loop = nullptr; + napi_get_uv_event_loop(reinterpret_cast(&jsRuntime_.GetNativeEngine()), &loop); + std::shared_ptr work = std::make_shared(); + if (work == nullptr) { + HILOG_ERROR("failed to new uv_work_t"); + return nullptr; + } + work->data = reinterpret_cast(param.get()); + uv_queue_work(loop, work.get(), [](uv_work_t *work) {}, [](uv_work_t *work, int status) { + CallbackParam *param = reinterpret_cast(work->data); + if (!DoAsnycWork(param)) { + HILOG_ERROR("failed to call DoAsnycWork"); + } + std::unique_lock lock(param->lockInfo->fileOperateMutex); + param->lockInfo->isReady = true; + param->lockInfo->fileOperateCondition.notify_all(); + }); + std::unique_lock lock(param->lockInfo->fileOperateMutex); + param->lockInfo->fileOperateCondition.wait(lock, [param]() { return param->lockInfo->isReady; }); + return std::move(param->result); +} + void JsFileExtAbility::GetSrcPath(std::string &srcPath) { HILOG_INFO("%{public}s begin.", __func__); @@ -179,7 +244,7 @@ int JsFileExtAbility::OpenFile(const Uri &uri, int flags) NativeValue* nativeUri = reinterpret_cast(napiUri); NativeValue* nativeFlags = reinterpret_cast(napiFlags); NativeValue* argv[] = {nativeUri, nativeFlags}; - NativeValue* nativeResult = CallObjectMethod("openFile", argv, ARGC_TWO); + NativeValue* nativeResult = AsnycCallObjectMethod("openFile", argv, ARGC_TWO); int ret = -1; if (nativeResult == nullptr) { HILOG_ERROR("%{public}s call openFile with return null.", __func__); @@ -204,7 +269,7 @@ int JsFileExtAbility::CreateFile(const Uri &parentUri, const std::string &displa NativeValue* nativeParentUri = reinterpret_cast(napiParentUri); NativeValue* nativeDisplayName = reinterpret_cast(napiDisplayName); NativeValue* argv[] = {nativeParentUri, nativeDisplayName}; - NativeValue* nativeResult = CallObjectMethod("createFile", argv, ARGC_TWO); + NativeValue* nativeResult = AsnycCallObjectMethod("createFile", argv, ARGC_TWO); int ret = -1; if (nativeResult == nullptr) { HILOG_ERROR("%{public}s call createFile with return null.", __func__); @@ -236,7 +301,7 @@ int JsFileExtAbility::Mkdir(const Uri &parentUri, const std::string &displayName NativeValue* nativeParentUri = reinterpret_cast(napiParentUri); NativeValue* nativeDisplayName = reinterpret_cast(napiDisplayName); NativeValue* argv[] = {nativeParentUri, nativeDisplayName}; - NativeValue* nativeResult = CallObjectMethod("mkdir", argv, ARGC_TWO); + NativeValue* nativeResult = AsnycCallObjectMethod("mkdir", argv, ARGC_TWO); int ret = -1; if (nativeResult == nullptr) { HILOG_ERROR("%{public}s call Mkdir with return null.", __func__); @@ -265,7 +330,7 @@ int JsFileExtAbility::Delete(const Uri &sourceFileUri) NativeValue* nativeUri = reinterpret_cast(napiUri); NativeValue* argv[] = {nativeUri}; - NativeValue* nativeResult = CallObjectMethod("delete", argv, ARGC_ONE); + NativeValue* nativeResult = AsnycCallObjectMethod("delete", argv, ARGC_ONE); int ret = -1; if (nativeResult == nullptr) { HILOG_ERROR("%{public}s call delete with return null.", __func__); @@ -289,7 +354,7 @@ int JsFileExtAbility::Move(const Uri &sourceFileUri, const Uri &targetParentUri, NativeValue* nativeSourceFileUri = reinterpret_cast(napiSourceFileUri); NativeValue* nativeTargetParentUri = reinterpret_cast(napiTargetParentUri); NativeValue* argv[] = {nativeSourceFileUri, nativeTargetParentUri}; - NativeValue* nativeResult = CallObjectMethod("move", argv, ARGC_TWO); + NativeValue* nativeResult = AsnycCallObjectMethod("move", argv, ARGC_TWO); int ret = -1; if (nativeResult == nullptr) { HILOG_ERROR("%{public}s call move with return null.", __func__); @@ -321,7 +386,7 @@ int JsFileExtAbility::Rename(const Uri &sourceFileUri, const std::string &displa NativeValue* nativeSourceFileUri = reinterpret_cast(napiSourceFileUri); NativeValue* nativeDisplayName = reinterpret_cast(napiDisplayName); NativeValue* argv[] = {nativeSourceFileUri, nativeDisplayName}; - NativeValue* nativeResult = CallObjectMethod("rename", argv, ARGC_TWO); + NativeValue* nativeResult = AsnycCallObjectMethod("rename", argv, ARGC_TWO); int ret = -1; if (nativeResult == nullptr) { HILOG_ERROR("%{public}s call rename with return null.", __func__); @@ -351,7 +416,7 @@ std::vector JsFileExtAbility::ListFile(const Uri &sourceFileUri) NativeValue* nativeUri = reinterpret_cast(napiUri); NativeValue* argv[] = {nativeUri}; - NativeValue* nativeResult = CallObjectMethod("listFile", argv, ARGC_ONE); + NativeValue* nativeResult = AsnycCallObjectMethod("listFile", argv, ARGC_ONE); if (nativeResult == nullptr) { HILOG_ERROR("%{public}s call listFile with return null.", __func__); return vec; @@ -373,7 +438,7 @@ std::vector JsFileExtAbility::GetRoots() std::vector vec; NativeValue* argv[] = {}; - NativeValue* nativeResult = CallObjectMethod("getRoots", argv, ARGC_ZERO); + NativeValue* nativeResult = AsnycCallObjectMethod("getRoots", argv, ARGC_ZERO); if (nativeResult == nullptr) { HILOG_ERROR("%{public}s call getRoots with return null.", __func__); return vec;