diff --git a/interfaces/kits/js/src/mod_fs/properties/open.cpp b/interfaces/kits/js/src/mod_fs/properties/open.cpp new file mode 100644 index 0000000000000000000000000000000000000000..40acdf0af95f46f98fd91a5fdf88624334637fba --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/open.cpp @@ -0,0 +1,211 @@ +/* + * 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 "open.h" + +#include +#include +#include +#include +#include + +#include "../common_func.h" +#include "ability.h" +#include "class_file/file_entity.h" +#include "class_file/file_n_exporter.h" +#include "datashare_helper.h" +#include "filemgmt_libhilog.h" +#include "filemgmt_libn.h" +#include "remote_uri.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; +using namespace OHOS::FileManagement::LibN; + +static tuple GetJsFlags(napi_env env, const NFuncArg &funcArg) +{ + int mode = O_RDONLY; + bool succ = false; + if (funcArg.GetArgc() >= NARG_CNT::TWO && NVal(env, funcArg[NARG_POS::SECOND]).TypeIs(napi_number)) { + tie(succ, mode) = NVal(env, funcArg[NARG_POS::SECOND]).ToInt32(); + if (!succ) { + HILOGE("Invalid mode"); + NError(EINVAL).ThrowErr(env); + return { false, mode }; + } + (void)CommonFunc::ConvertJsFlags(mode); + } + return { true, mode }; +} + +static NVal InstantiateFile(napi_env env, int fd, string pathOrUri, bool isUri) +{ + napi_value objFile = NClass::InstantiateClass(env, FileNExporter::className_, {}); + if (!objFile) { + HILOGE("Failed to instantiate class"); + NError(EIO).ThrowErr(env); + return NVal(); + } + + auto fileEntity = NClass::GetEntityOf(env, objFile); + if (!fileEntity) { + HILOGE("Failed to get fileEntity"); + NError(EIO).ThrowErr(env); + return NVal(); + } + auto fdg = make_unique(fd, false); + fileEntity->fd_.swap(fdg); + if (isUri) { + fileEntity->path_ = ""; + fileEntity->uri_ = pathOrUri; + } else { + fileEntity->path_ = pathOrUri; + fileEntity->uri_ = ""; + } + return { env, objFile }; +} + +static int OpenFileByDatashare(napi_env env, napi_value argv, string path) +{ + std::shared_ptr dataShareHelper = nullptr; + int fd = -1; + sptr remote = new (std::nothrow) IRemoteStub(); + if (remote == nullptr) { + return ENOMEM; + } + + dataShareHelper = DataShare::DataShareHelper::Creator(remote->AsObject(), MEDIALIBRARY_DATA_URI); + Uri uri(path); + fd = dataShareHelper->OpenFile(uri, MEDIA_FILEMODE_READONLY); + return fd; +} + +napi_value Open::Sync(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + auto [succPath, path, ignore] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!succPath) { + HILOGE("Invalid path"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + auto [succMode, mode] = GetJsFlags(env, funcArg); + if (!succMode) { + HILOGE("Invalid mode"); + return nullptr; + } + if (DistributedFS::ModuleRemoteUri::RemoteUri::IsMediaUri(path.get())) { + auto fd = OpenFileByDatashare(env, funcArg[NARG_POS::FIRST], path.get()); + if (fd >= 0) { + auto file = InstantiateFile(env, fd, path.get(), true).val_; + return file; + } + HILOGE("Failed to open file by Datashare"); + NError(-1).ThrowErr(env); + return nullptr; + } + std::unique_ptr open_req = { new uv_fs_t, uv_fs_req_cleanup }; + int ret = uv_fs_open(uv_default_loop(), open_req.get(), path.get(), mode, S_IRUSR | + S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, NULL); + if (ret < 0) { + HILOGE("Failed to open file for libuv error %{public}d", ret); + NError(errno).ThrowErr(env); + return nullptr; + } + auto file = InstantiateFile(env, open_req.get()->result, path.get(), false).val_; + return file; +} + +struct AsyncOpenFileArg { + int fd; + string path; + string uri; +}; + +napi_value Open::Async(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::THREE)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + auto [succPath, path, ignore] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!succPath) { + HILOGE("Invalid path"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + auto [succMode, mode] = GetJsFlags(env, funcArg); + if (!succMode) { + HILOGE("Invalid mode"); + return nullptr; + } + auto arg = make_shared(); + auto argv = funcArg[NARG_POS::FIRST]; + auto cbExec = [arg, argv, path = string(path.get()), mode = mode, env = env]() -> NError { + if (DistributedFS::ModuleRemoteUri::RemoteUri::IsMediaUri(path)) { + auto fd = OpenFileByDatashare(env, argv, path); + if (fd >= 0) { + arg->fd = fd; + arg->path = ""; + arg->uri = path; + return NError(ERRNO_NOERR); + } + HILOGE("Failed to open file by Datashare"); + return NError(-1); + } + std::unique_ptr open_req = { new uv_fs_t, uv_fs_req_cleanup }; + int ret = uv_fs_open(uv_default_loop(), open_req.get(), path.c_str(), mode, S_IRUSR | + S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, NULL); + if (ret < 0) { + HILOGE("Failed to open file for libuv error %{public}d", ret); + return NError(errno); + } + arg->fd = open_req.get()->result; + arg->path = path; + arg->uri = ""; + return NError(ERRNO_NOERR); + }; + auto cbCompl = [arg](napi_env env, NError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } + bool isUri = false; + if (arg->path.empty() && arg->uri.size()) { + isUri = true; + return InstantiateFile(env, arg->fd, arg->uri, isUri); + } + return InstantiateFile(env, arg->fd, arg->path, isUri); + }; + NVal thisVar(env, funcArg.GetThisVar()); + if (funcArg.GetArgc() == NARG_CNT::ONE || (funcArg.GetArgc() == NARG_CNT::TWO && + NVal(env, funcArg[NARG_POS::SECOND]).TypeIs(napi_number))) { + return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_OPEN_NAME, cbExec, cbCompl).val_; + } else { + int cbIdx = ((funcArg.GetArgc() == NARG_CNT::THREE) ? NARG_POS::THIRD : NARG_POS::SECOND); + NVal cb(env, funcArg[cbIdx]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_OPEN_NAME, cbExec, cbCompl).val_; + } +} +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/open.h b/interfaces/kits/js/src/mod_fs/properties/open.h new file mode 100644 index 0000000000000000000000000000000000000000..8bf564bbb12504369d02c3c01223895a12c84411 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/open.h @@ -0,0 +1,45 @@ +/* + * 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 INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_OPEN_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_OPEN_H + +#include "iremote_broker.h" +#include "../../common/napi/uni_header.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +class Open final { +public: + static napi_value Async(napi_env env, napi_callback_info info); + static napi_value Sync(napi_env env, napi_callback_info info); +}; + +class FileIoToken : public IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"ohos.fileio.open"); + + FileIoToken() = default; + virtual ~FileIoToken() noexcept = default; +}; + +const std::string PROCEDURE_OPEN_NAME = "FileIOOpen"; +const std::string MEDIALIBRARY_DATA_URI = "datashare:///media"; +const std::string MEDIA_FILEMODE_READONLY = "r"; +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_OPEN_H \ No newline at end of file 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 9022199a953d94d6cdc332b342e29e884a7fcea1..d3a3701e6dcc1ab28c6d303319661c34c43c34f6 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 @@ -24,10 +24,10 @@ #include #include "../common_func.h" - +#include "class_file/file_entity.h" +#include "class_file/file_n_exporter.h" #include "filemgmt_libn.h" -#include "../class_file/file_entity.h" -#include "../class_file/file_n_exporter.h" +#include "open.h" namespace OHOS { namespace FileManagement { @@ -266,6 +266,8 @@ napi_value PropNExporter::WriteSync(napi_env env, napi_callback_info info) bool PropNExporter::Export() { return exports_.AddProp({ + NVal::DeclareNapiFunction("open", Open::Async), + NVal::DeclareNapiFunction("openSync", Open::Sync), NVal::DeclareNapiFunction("read", Read), NVal::DeclareNapiFunction("readSync", ReadSync), NVal::DeclareNapiFunction("write", Write), diff --git a/utils/filemgmt_libhilog/filemgmt_libhilog.h b/utils/filemgmt_libhilog/filemgmt_libhilog.h index b485c17742d998004ffb2a7eeb6a3b5615000266..5f4c18b87aae41fe911ae8f2cc7f6e5cb98ae07c 100644 --- a/utils/filemgmt_libhilog/filemgmt_libhilog.h +++ b/utils/filemgmt_libhilog/filemgmt_libhilog.h @@ -22,15 +22,9 @@ namespace OHOS { namespace FileManagement { -#ifndef LOG_DOMAIN -#define LOG_DOMAIN 0xD004388 -#endif - -#ifndef LOG_TAG -#define LOG_TAG "file_api" -#endif -static constexpr HiviewDFX::HiLogLabel FILEMGMT_LOG_LABEL = {LOG_CORE, LOG_DOMAIN, LOG_TAG}; +static constexpr int FILEFS_LOG_DOMAIN = 0xD004388; +static constexpr HiviewDFX::HiLogLabel FILEMGMT_LOG_LABEL = {LOG_CORE, FILEFS_LOG_DOMAIN, "file_api"}; #if defined __FILE_NAME__ #define FILEMGMT_FILE_NAME __FILE_NAME__