diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..4947287f --- /dev/null +++ b/LICENSE @@ -0,0 +1,177 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/README.md b/README.md index 1b2468c0..12b248b0 100644 --- a/README.md +++ b/README.md @@ -1,39 +1,69 @@ -# storage_user_file_manger +# File Mangaer Service公共文件管理服务 -#### 介绍 -{**以下是 Gitee 平台说明,您可以替换此简介** -Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台 -无论是个人、团队、或是企业,都能够用 Gitee 实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)} - -#### 软件架构 -软件架构说明 +- [简介](#section1158716411637) +- [目录](#section161941989596) +- [使用说明](#usage-guidelines) + - [创建文件](#get-audioasset) +- [相关仓](#section1533973044317) -#### 安装教程 +## 简介 -1. xxxx -2. xxxx -3. xxxx +**File Mangaer Service**公共文件管理服务仓库提供了公共文件管理接口。File Mangaer Service接口暂不对外部应用开放, 仅内部使用。 -#### 使用说明 - -1. xxxx -2. xxxx -3. xxxx - -#### 参与贡献 - -1. Fork 本仓库 -2. 新建 Feat_xxx 分支 -3. 提交代码 -4. 新建 Pull Request +支持能力列举如下: +- 公共文件路径下媒体文件查询,创建 +- 公共文件路径下文档文件查询、创建 -#### 特技 +## 目录 -1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md -2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) -3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 -4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 -5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) -6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) +仓目录结构如下: +``` +/foundation/storage/user_file_manger # fms组件代码 +├── serivce # 框架代码 +│   ├── etc # 内部接口实现 +│   ├── src # 内部接口实现 +├── interfaces # 接口代码 +│   ├── innerkits # 内部 Native 接口 +│   └── kits # 外部 JS 接口 +├── LICENSE # 证书文件 +├── ohos.build # 编译文件 +├── sa_profile # 服务配置文件 +└── services # 服务实现 +``` + +## 使用说明 +### 创建文件 +1. + ``` + 接口流程 + 应用通过接口让媒体库创建文件,返回文件uri, 应用自己通过openfile打开uri,获取fd进行文件操作。 + + // 应用A + // 拉起filepicker 获取 uri + import media_library from '@ohos.media_library' + fd = media_library.openfile(uri) + fileio.write(fd, data) + fileio.close() + + // file picker 流程 + // media_path通过filepicker获取待保存目录uri + import filemanager from '@ohos.filemanager' + let media_path = "xxxx" + let name = "xxxx" + filemanager.createFile(name,media_path) + .then((uri) => { + // success + }) + .catch(function(err) { + //类型错误,重名... + // fail + }) + + // FMS + mediaLib.createAsset(name) + return fileuri + ``` + +## 相关仓 diff --git a/interfaces/kits/js/BUILD.gn b/interfaces/kits/js/BUILD.gn new file mode 100644 index 00000000..607a7524 --- /dev/null +++ b/interfaces/kits/js/BUILD.gn @@ -0,0 +1,67 @@ +# 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. + +import("//build/ohos.gni") +FMS_BASE_DIR = "//foundation/storage/services" + +ohos_shared_library("filemanager") { + subsystem_name = "storage" + part_name = "filemanager" + + relative_install_dir = "module" + + include_dirs = [ + # "$BASE_DIR/napi", + "//third_party/node/src", + "//foundation/ace/napi/interfaces/kits", + "//utils/native/base/include", + "//third_party/libuv/include", + "$FMS_BASE_DIR/include", + "$FMS_BASE_DIR/src/client", + "$FMS_BASE_DIR/src/server", + "$FMS_BASE_DIR/src/fileoper", + ] + + sources = [ + "src/common/napi/n_async/n_async_work_callback.cpp", + "src/common/napi/n_async/n_async_work_promise.cpp", + "src/common/napi/n_async/n_ref.cpp", + "src/common/napi/n_class.cpp", + "src/common/napi/n_func_arg.cpp", + "src/common/napi/n_val.cpp", + "src/common/uni_error.cpp", + "src/module.cpp", + "src/fms_napi.cpp", + ] + + deps = [ + "//utils/native/base:utils", + "$FMS_BASE_DIR:fms_server", + "//foundation/ace/napi:ace_napi", + ] + cflags = [] + if (target_cpu == "arm") { + cflags += [ "-DBINDER_IPC_32BIT" ] + } + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + "safwk:system_ability_fwk", + "samgr_standard:samgr_proxy", + ] +} + + + + + diff --git a/interfaces/kits/js/src/common/napi/n_async/n_async_context.h b/interfaces/kits/js/src/common/napi/n_async/n_async_context.h new file mode 100644 index 00000000..67dcdde7 --- /dev/null +++ b/interfaces/kits/js/src/common/napi/n_async/n_async_context.h @@ -0,0 +1,69 @@ +/* + * 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. + */ + +#pragma once + +#include +#include + +#include "../../uni_error.h" +#include "../n_val.h" +#include "../uni_header.h" +#include "n_ref.h" + +namespace OHOS { +namespace DistributedFS { +typedef std::function NContextCBExec; +typedef std::function NContextCBComplete; + +class NAsyncContext { +public: + UniError err_; + NVal res_; + NContextCBExec cbExec_; + NContextCBComplete cbComplete_; + napi_async_work awork_; + NRef thisPtr_; + + explicit NAsyncContext(NVal thisPtr) : thisPtr_(thisPtr) {} + ~NAsyncContext() = default; +}; + +class NAsyncContextPromise : public NAsyncContext { +public: + napi_deferred deferred_; + explicit NAsyncContextPromise(NVal thisPtr) : NAsyncContext(thisPtr) {} + ~NAsyncContextPromise() = default; +}; + +class NAsyncContextCallback : public NAsyncContext { +public: + NRef cb_; + NAsyncContextCallback(NVal thisPtr, NVal cb) : NAsyncContext(thisPtr), cb_(cb) {} + ~NAsyncContextCallback() = default; +}; + +class NAsyncContextLegacy : public NAsyncContext { +public: + NRef cbSucc_; + NRef cbFail_; + NRef cbFinal_; + NAsyncContextLegacy(NVal thisPtr, NVal cbSucc, NVal cbFail, NVal cbFinal) + : NAsyncContext(thisPtr), cbSucc_(cbSucc), cbFail_(cbFail), cbFinal_(cbFinal) + {} + ~NAsyncContextLegacy() = default; +}; +} // namespace DistributedFS +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/common/napi/n_async/n_async_work_callback.cpp b/interfaces/kits/js/src/common/napi/n_async/n_async_work_callback.cpp new file mode 100644 index 00000000..d9c05c02 --- /dev/null +++ b/interfaces/kits/js/src/common/napi/n_async/n_async_work_callback.cpp @@ -0,0 +1,103 @@ +/* + * 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 "n_async_work_callback.h" + +#include +#include + +#include "log.h" + +namespace OHOS { +namespace DistributedFS { +using namespace std; + +NAsyncWorkCallback::NAsyncWorkCallback(napi_env env, NVal thisPtr, NVal cb) : NAsyncWorkFactory(env) +{ + ctx_ = new NAsyncContextCallback(thisPtr, cb); +} +NAsyncWorkCallback::NAsyncWorkCallback(const NAsyncWorkCallback &in, napi_env env) : NAsyncWorkFactory(env) +{ + delete ctx_; + this->ctx_ = new NAsyncContextCallback(in.ctx_->thisPtr_.Deref(env), in.ctx_->cb_.Deref(env)); +} + +static void CallbackExecute(napi_env env, void *data) +{ + auto ctx = static_cast(data); + if (ctx->cbExec_) { + ctx->err_ = ctx->cbExec_(env); + } +} +static void CallbackComplete(napi_env env, napi_status status, void *data) +{ + napi_handle_scope scope = nullptr; + napi_open_handle_scope(env, &scope); + auto ctx = static_cast(data); + if (ctx->cbComplete_) { + ctx->res_ = ctx->cbComplete_(env, ctx->err_); + ctx->cbComplete_ = nullptr; + } + + vector argv; + if (!ctx->res_.TypeIsError(true)) { + argv = { UniError(ERRNO_NOERR).GetNapiErr(env), ctx->res_.val_ }; + } else { + argv = { ctx->res_.val_ }; + } + + napi_value global = nullptr; + napi_value callback = ctx->cb_.Deref(env).val_; + napi_value tmp = nullptr; + napi_get_global(env, &global); + napi_status stat = napi_call_function(env, global, callback, argv.size(), argv.data(), &tmp); + if (stat != napi_ok) { + ERR_LOG("Failed to call function for %{public}d", stat); + } + napi_close_handle_scope(env, scope); + napi_delete_async_work(env, ctx->awork_); + delete ctx; +} + +NVal NAsyncWorkCallback::Schedule(string procedureName, NContextCBExec cbExec, NContextCBComplete cbComplete) +{ + if (!ctx_->cb_ || !ctx_->cb_.Deref(env_).TypeIs(napi_function)) { + UniError(EINVAL).ThrowErr(env_, "The callback shall be a funciton"); + return NVal(); + } + + ctx_->cbExec_ = move(cbExec); + ctx_->cbComplete_ = move(cbComplete); + + napi_value resource = NVal::CreateUTF8String(env_, procedureName).val_; + + napi_status status = + napi_create_async_work(env_, nullptr, resource, CallbackExecute, CallbackComplete, ctx_, &ctx_->awork_); + if (status != napi_ok) { + ERR_LOG("INNER BUG. Failed to create async work for %{public}d", status); + return NVal(); + } + + status = napi_queue_async_work(env_, ctx_->awork_); + if (status != napi_ok) { + ERR_LOG("INNER BUG. Failed to queue async work for %{public}d", status); + return NVal(); + } + + ctx_ = nullptr; // The ownership of ctx_ has been transfered + return NVal::CreateUndefined(env_); +} +} // namespace DistributedFS +} // namespace OHOS diff --git a/interfaces/kits/js/src/common/napi/n_async/n_async_work_callback.h b/interfaces/kits/js/src/common/napi/n_async/n_async_work_callback.h new file mode 100644 index 00000000..a700a4ef --- /dev/null +++ b/interfaces/kits/js/src/common/napi/n_async/n_async_work_callback.h @@ -0,0 +1,37 @@ +/* + * 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. + */ + +#pragma once + +#include +#include +#include + +#include "n_async_work_factory.h" + +namespace OHOS { +namespace DistributedFS { +class NAsyncWorkCallback : public NAsyncWorkFactory { +public: + NAsyncWorkCallback(napi_env env, NVal thisPtr, NVal cb); + ~NAsyncWorkCallback() = default; + NAsyncWorkCallback(const NAsyncWorkCallback &in, napi_env env); + NVal Schedule(std::string procedureName, NContextCBExec cbExec, NContextCBComplete cbComplete) final; + +private: + NAsyncContextCallback *ctx_ = nullptr; +}; +} // namespace DistributedFS +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/common/napi/n_async/n_async_work_factory.h b/interfaces/kits/js/src/common/napi/n_async/n_async_work_factory.h new file mode 100644 index 00000000..bd993e5d --- /dev/null +++ b/interfaces/kits/js/src/common/napi/n_async/n_async_work_factory.h @@ -0,0 +1,35 @@ +/* + * 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. + */ + +#pragma once + +#include +#include +#include + +#include "n_async_context.h" + +namespace OHOS { +namespace DistributedFS { +class NAsyncWorkFactory { +public: + explicit NAsyncWorkFactory(napi_env env) : env_(env) {} + ~NAsyncWorkFactory() = default; + virtual NVal Schedule(std::string procedureName, NContextCBExec cbExec, NContextCBComplete cbComplete) = 0; + + napi_env env_ = nullptr; +}; +} // namespace DistributedFS +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/common/napi/n_async/n_async_work_promise.cpp b/interfaces/kits/js/src/common/napi/n_async/n_async_work_promise.cpp new file mode 100644 index 00000000..727f8269 --- /dev/null +++ b/interfaces/kits/js/src/common/napi/n_async/n_async_work_promise.cpp @@ -0,0 +1,98 @@ +/* + * 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 "n_async_work_promise.h" + +#include +#include +#include + +#include "log.h" + +namespace OHOS { +namespace DistributedFS { +using namespace std; + +NAsyncWorkPromise::NAsyncWorkPromise(napi_env env, NVal thisPtr) : NAsyncWorkFactory(env) +{ + ctx_ = new NAsyncContextPromise(thisPtr); +} +NAsyncWorkPromise::NAsyncWorkPromise(const NAsyncWorkPromise &in, napi_env env) : NAsyncWorkFactory(env) +{ + delete ctx_; + ctx_ = new NAsyncContextPromise(in.ctx_->thisPtr_.Deref(env)); +} + +static void PromiseOnExec(napi_env env, void *data) +{ + auto ctx = static_cast(data); + if (ctx->cbExec_) { + ctx->err_ = ctx->cbExec_(env); + } +} +static void PromiseOnComplete(napi_env env, napi_status status, void *data) +{ + auto ctx = static_cast(data); + if (ctx->cbComplete_) { + ctx->res_ = ctx->cbComplete_(env, ctx->err_); + } + if (!ctx->res_.TypeIsError(true)) { + napi_status status = napi_resolve_deferred(env, ctx->deferred_, ctx->res_.val_); + if (status != napi_ok) { + ERR_LOG("Internal BUG, cannot resolve promise for %{public}d", status); + } + } else { + napi_status status = napi_reject_deferred(env, ctx->deferred_, ctx->res_.val_); + if (status != napi_ok) { + ERR_LOG("Internal BUG, cannot reject promise for %{public}d", status); + } + } + ctx->deferred_ = nullptr; + napi_delete_async_work(env, ctx->awork_); + delete ctx; +} + + +NVal NAsyncWorkPromise::Schedule(string procedureName, NContextCBExec cbExec, NContextCBComplete cbComplete) +{ + ctx_->cbExec_ = move(cbExec); + ctx_->cbComplete_ = move(cbComplete); + + napi_status status; + napi_value result = nullptr; + status = napi_create_promise(env_, &ctx_->deferred_, &result); + if (status != napi_ok) { + ERR_LOG("INNER BUG. Cannot create promise for %{public}d", status); + return NVal(); + } + + napi_value resource = NVal::CreateUTF8String(env_, procedureName).val_; + status = napi_create_async_work(env_, nullptr, resource, PromiseOnExec, PromiseOnComplete, ctx_, &ctx_->awork_); + if (status != napi_ok) { + ERR_LOG("INNER BUG. Failed to create async work for %{public}d", status); + return NVal(); + } + + status = napi_queue_async_work(env_, ctx_->awork_); + if (status != napi_ok) { + ERR_LOG("INNER BUG. Failed to queue async work for %{public}d", status); + return NVal(); + } + + ctx_ = nullptr; // The ownership of ctx_ has been transfered + return { env_, result }; +} +} // namespace DistributedFS +} // namespace OHOS diff --git a/interfaces/kits/js/src/common/napi/n_async/n_async_work_promise.h b/interfaces/kits/js/src/common/napi/n_async/n_async_work_promise.h new file mode 100644 index 00000000..9bef0eba --- /dev/null +++ b/interfaces/kits/js/src/common/napi/n_async/n_async_work_promise.h @@ -0,0 +1,36 @@ +/* + * 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. + */ + +#pragma once + +#include +#include + +#include "n_async_work_factory.h" + +namespace OHOS { +namespace DistributedFS { +class NAsyncWorkPromise : public NAsyncWorkFactory { +public: + NAsyncWorkPromise(napi_env env, NVal thisPtr); + ~NAsyncWorkPromise() = default; + NAsyncWorkPromise(const NAsyncWorkPromise &in, napi_env env); + NVal Schedule(std::string procedureName, NContextCBExec cbExec, NContextCBComplete cbComplete) final; + +private: + NAsyncContextPromise *ctx_; +}; +} // namespace DistributedFS +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/common/napi/n_async/n_ref.cpp b/interfaces/kits/js/src/common/napi/n_async/n_ref.cpp new file mode 100644 index 00000000..8b78ac9c --- /dev/null +++ b/interfaces/kits/js/src/common/napi/n_async/n_ref.cpp @@ -0,0 +1,53 @@ +/* + * 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 "n_ref.h" + +namespace OHOS { +namespace DistributedFS { +NRef::NRef() {} + +NRef::NRef(NVal val) +{ + if (val) { + env_ = val.env_; + napi_create_reference(val.env_, val.val_, 1, &ref_); + } +} + +NRef::~NRef() +{ + if (ref_) { + napi_delete_reference(env_, ref_); + } +} + +NRef::operator bool() const +{ + return ref_ != nullptr; +} + +NVal NRef::Deref(napi_env env) +{ + if (!ref_) { + return NVal(); + } + + napi_value val = nullptr; + napi_get_reference_value(env, ref_, &val); + return { env, val }; +} +} // namespace DistributedFS +} // namespace OHOS diff --git a/interfaces/kits/js/src/common/napi/n_async/n_ref.h b/interfaces/kits/js/src/common/napi/n_async/n_ref.h new file mode 100644 index 00000000..12b216ab --- /dev/null +++ b/interfaces/kits/js/src/common/napi/n_async/n_ref.h @@ -0,0 +1,37 @@ +/* + * 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. + */ + +#pragma once + +#include "../n_val.h" +#include "../uni_header.h" + +namespace OHOS { +namespace DistributedFS { +class NRef { +public: + NRef(); + explicit NRef(NVal val); + ~NRef(); + + explicit operator bool() const; + NVal Deref(napi_env env); + +private: + napi_env env_ = nullptr; + napi_ref ref_ = nullptr; +}; +} // namespace DistributedFS +} // namespace OHOS diff --git a/interfaces/kits/js/src/common/napi/n_class.cpp b/interfaces/kits/js/src/common/napi/n_class.cpp new file mode 100644 index 00000000..c6c60ee9 --- /dev/null +++ b/interfaces/kits/js/src/common/napi/n_class.cpp @@ -0,0 +1,99 @@ +/* + * 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 "n_class.h" + +#include +#include + +#include "log.h" + +namespace OHOS { +namespace DistributedFS { +using namespace std; +NClass &NClass::GetInstance() +{ + static NClass nClass; + return nClass; +} + +tuple NClass::DefineClass(napi_env env, + string className, + napi_callback constructor, + vector &&properties) +{ + napi_value classVal = nullptr; + napi_status stat = napi_define_class(env, + className.c_str(), + className.length(), + constructor, + nullptr, + properties.size(), + properties.data(), + &classVal); + if (stat != napi_ok) { + ERR_LOG("INNER BUG. Cannot define class %{public}s because of %{public}d", className.c_str(), stat); + } + return { stat == napi_ok, classVal }; +} + +bool NClass::SaveClass(napi_env env, string className, napi_value exClass) +{ + NClass &nClass = NClass::GetInstance(); + lock_guard(nClass.exClassMapLock); + + if (nClass.exClassMap.find(className) != nClass.exClassMap.end()) { + return true; + } + + napi_ref constructor; + napi_status res = napi_create_reference(env, exClass, 1, &constructor); + if (res == napi_ok) { + nClass.exClassMap.insert({ className, constructor }); + INFO_LOG("Class %{public}s has been saved", className.c_str()); + } else { + ERR_LOG("INNER BUG. Cannot ref class constructor %{public}s because of %{public}d", className.c_str(), res); + } + return res == napi_ok; +} + +napi_value NClass::InstantiateClass(napi_env env, string className, vector args) +{ + NClass &nClass = NClass::GetInstance(); + lock_guard(nClass.exClassMapLock); + + auto it = nClass.exClassMap.find(className); + if (it == nClass.exClassMap.end()) { + ERR_LOG("Class %{public}s hasn't been saved yet", className.c_str()); + return nullptr; + } + + napi_value cons = nullptr; + napi_status status = napi_get_reference_value(env, it->second, &cons); + if (status != napi_ok) { + ERR_LOG("INNER BUG. Cannot deref class %{public}s because of %{public}d", className.c_str(), status); + return nullptr; + } + + napi_value instance = nullptr; + status = napi_new_instance(env, cons, args.size(), args.data(), &instance); + if (status != napi_ok) { + ERR_LOG("INNER BUG. Cannot instantiate the class %{public}s because of %{public}d", className.c_str(), status); + return nullptr; + } + return instance; +} +} // namespace DistributedFS +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/common/napi/n_class.h b/interfaces/kits/js/src/common/napi/n_class.h new file mode 100644 index 00000000..e048ae80 --- /dev/null +++ b/interfaces/kits/js/src/common/napi/n_class.h @@ -0,0 +1,82 @@ +/* + * 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. + */ + +#pragma once + +#include "uni_header.h" + +#include +#include +#include +#include +#include +#include + +#include "log.h" + +namespace OHOS { +namespace DistributedFS { +class NClass final { +public: + NClass(const NClass &) = delete; + NClass &operator = (const NClass &) = delete; + static NClass &GetInstance(); + + static std::tuple DefineClass(napi_env env, + std::string className, + napi_callback constructor, + std::vector &&properties); + static bool SaveClass(napi_env env, std::string className, napi_value exClass); + static napi_value InstantiateClass(napi_env env, std::string className, std::vector args); + + template static T *GetEntityOf(napi_env env, napi_value objStat) + { + if (!env || !objStat) { + ERR_LOG("Empty input: env %d, obj %d", env == nullptr, objStat == nullptr); + return nullptr; + } + T *t = nullptr; + napi_status status = napi_unwrap(env, objStat, (void **)&t); + if (status != napi_ok) { + ERR_LOG("Cannot umwarp for pointer: %d", status); + return nullptr; + } + return t; + } + + template static bool SetEntityFor(napi_env env, napi_value obj, std::unique_ptr entity) + { + napi_status status = napi_wrap( + env, + obj, + entity.get(), + [](napi_env env, void *data, void *hint) { + auto entity = static_cast(data); + delete entity; + }, + nullptr, + nullptr); + entity.release(); + return status == napi_ok; + } + +private: + NClass() = default; + ~NClass() = default; + std::map exClassMap; + std::mutex exClassMapLock; +}; +} // namespace DistributedFS +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/common/napi/n_exporter.h b/interfaces/kits/js/src/common/napi/n_exporter.h new file mode 100644 index 00000000..2ade0c07 --- /dev/null +++ b/interfaces/kits/js/src/common/napi/n_exporter.h @@ -0,0 +1,39 @@ +/* + * 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. + */ + +#pragma once + +#include "uni_header.h" + +#include +#include + +#include "n_val.h" + +namespace OHOS { +namespace DistributedFS { +class NExporter { +public: + NExporter(napi_env env, napi_value exports) : exports_(env, exports) {}; + virtual ~NExporter() = default; + + virtual bool Export() = 0; + virtual std::string GetClassName() = 0; + +protected: + NVal exports_; +}; +} // namespace DistributedFS +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/common/napi/n_func_arg.cpp b/interfaces/kits/js/src/common/napi/n_func_arg.cpp new file mode 100644 index 00000000..ed3a5ec7 --- /dev/null +++ b/interfaces/kits/js/src/common/napi/n_func_arg.cpp @@ -0,0 +1,111 @@ +/* + * 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 "n_func_arg.h" + +#include +#include + +#include "log.h" +#include "../uni_error.h" + +namespace OHOS { +namespace DistributedFS { +using namespace std; + +NFuncArg::NFuncArg(napi_env env, napi_callback_info info) : env_(env), info_(info) {} + +NFuncArg::~NFuncArg() {} + +void NFuncArg::SetArgc(size_t argc) +{ + argc_ = argc; +} +void NFuncArg::SetThisVar(napi_value thisVar) +{ + thisVar_ = thisVar; +} + +size_t NFuncArg::GetArgc(void) const +{ + return argc_; +} + +napi_value NFuncArg::GetThisVar(void) const +{ + return thisVar_; +} + +napi_value NFuncArg::GetArg(size_t argPos) const +{ + return (argPos < GetArgc()) ? argv_[argPos] : nullptr; +} + +napi_value NFuncArg::operator[](size_t argPos) const +{ + return GetArg(argPos); +} + +bool NFuncArg::InitArgs(std::function argcChecker) +{ + SetArgc(0); + argv_.reset(); + + size_t argc; + napi_value thisVar; + napi_status status = napi_get_cb_info(env_, info_, &argc, nullptr, &thisVar, nullptr); + if (status != napi_ok) { + ERR_LOG("Cannot get num of func args for %{public}d", status); + return false; + } + if (argc) { + argv_ = make_unique(argc); + status = napi_get_cb_info(env_, info_, &argc, argv_.get(), &thisVar, nullptr); + if (status != napi_ok) { + ERR_LOG("Cannot get func args for %{public}d", status); + return false; + } + } + SetArgc(argc); + SetThisVar(thisVar); + + return argcChecker(); +} + +bool NFuncArg::InitArgs(size_t argc) +{ + return InitArgs([argc, this]() { + size_t realArgc = GetArgc(); + if (argc != realArgc) { + ERR_LOG("Num of args recved eq %zu while expecting %{public}zu", realArgc, argc); + return false; + } + return true; + }); +} + +bool NFuncArg::InitArgs(size_t minArgc, size_t maxArgc) +{ + return InitArgs([minArgc, maxArgc, this]() { + size_t realArgc = GetArgc(); + if (minArgc > realArgc || maxArgc < realArgc) { + ERR_LOG("Num of args recved eq %zu while expecting %{public}zu ~ %{public}zu", realArgc, minArgc, maxArgc); + return false; + } + return true; + }); +} +} // namespace DistributedFS +} // namespace OHOS diff --git a/interfaces/kits/js/src/common/napi/n_func_arg.h b/interfaces/kits/js/src/common/napi/n_func_arg.h new file mode 100644 index 00000000..7ff5b294 --- /dev/null +++ b/interfaces/kits/js/src/common/napi/n_func_arg.h @@ -0,0 +1,71 @@ +/* + * 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. + */ + +#pragma once + +#include +#include +#include +#include + +#include "n_val.h" +#include "uni_header.h" + +namespace OHOS { +namespace DistributedFS { +enum NARG_CNT { + ZERO = 0, + ONE = 1, + TWO = 2, + THREE = 3, + FOUR = 4, +}; + +enum NARG_POS { + FIRST = 0, + SECOND = 1, + THIRD = 2, + FOURTH = 3, +}; + +class NFuncArg final { +public: + NFuncArg(napi_env env, napi_callback_info info); + virtual ~NFuncArg(); + + bool InitArgs(size_t argc); + bool InitArgs(size_t minArgc, size_t maxArgc); + + size_t GetArgc() const; + napi_value GetThisVar() const; + + napi_value operator[](size_t idx) const; + napi_value GetArg(size_t argPos) const; + +private: + napi_env env_ = nullptr; + napi_callback_info info_ = nullptr; + + size_t argc_ = 0; + std::unique_ptr argv_ = { nullptr }; + napi_value thisVar_ = nullptr; + + bool InitArgs(std::function argcChecker); + + void SetArgc(size_t argc); + void SetThisVar(napi_value thisVar); +}; +} // namespace DistributedFS +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/common/napi/n_val.cpp b/interfaces/kits/js/src/common/napi/n_val.cpp new file mode 100644 index 00000000..79a35d63 --- /dev/null +++ b/interfaces/kits/js/src/common/napi/n_val.cpp @@ -0,0 +1,306 @@ +/* + * 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 "n_val.h" + +#include +#include + +#include "log.h" +#include "../uni_error.h" + +namespace OHOS { +namespace DistributedFS { +using namespace std; + +NVal::NVal(napi_env nEnv, napi_value nVal = nullptr) : env_(nEnv), val_(nVal) {} + +NVal::operator bool() const +{ + return env_ && val_; +} + +bool NVal::TypeIs(napi_valuetype expType) const +{ + if (!*this) { + return false; + } + + napi_valuetype valueType; + napi_typeof(env_, val_, &valueType); + + if (expType != valueType) { + return false; + } + return true; +} + +bool NVal::TypeIsError(bool checkErrno) const +{ + if (!*this) { + return false; + } + + bool res = false; + napi_is_error(env_, val_, &res); + + return res; +} + +tuple, size_t> NVal::ToUTF8String() const +{ + size_t strLen = 0; + napi_status status = napi_get_value_string_utf8(env_, val_, nullptr, -1, &strLen); + if (status != napi_ok) { + return { false, nullptr, 0 }; + } + + size_t bufLen = strLen + 1; + unique_ptr str = make_unique(bufLen); + status = napi_get_value_string_utf8(env_, val_, str.get(), bufLen, &strLen); + return make_tuple(status == napi_ok, move(str), strLen); +} + +tuple, size_t> NVal::ToUTF16String() const +{ +#ifdef FILE_SUBSYSTEM_DEV_ON_PC + size_t strLen = 0; + napi_status status = napi_get_value_string_utf16(env_, val_, nullptr, -1, &strLen); + if (status != napi_ok) { + return { false, nullptr, 0 }; + } + + auto str = make_unique(++strLen); + status = napi_get_value_string_utf16(env_, val_, str.get(), strLen, nullptr); + if (status != napi_ok) { + return { false, nullptr, 0 }; + } + + strLen = reinterpret_cast(str.get() + strLen) - reinterpret_cast(str.get()); + auto strRet = unique_ptr(reinterpret_cast(str.release())); + return { true, move(strRet), strLen }; +#else + // Note that quickjs doesn't support utf16 + return ToUTF8String(); +#endif +} + +tuple NVal::ToPointer() const +{ + void *res = nullptr; + napi_status status = napi_get_value_external(env_, val_, &res); + return make_tuple(status == napi_ok, res); +} + +tuple NVal::ToBool() const +{ + bool flag = false; + napi_status status = napi_get_value_bool(env_, val_, &flag); + return make_tuple(status == napi_ok, flag); +} + +tuple NVal::ToInt32() const +{ + int32_t res = 0; + napi_status status = napi_get_value_int32(env_, val_, &res); + return make_tuple(status == napi_ok, res); +} + +tuple NVal::ToInt64() const +{ + int64_t res = 0; + napi_status status = napi_get_value_int64(env_, val_, &res); + return make_tuple(status == napi_ok, res); +} + +tuple NVal::ToArraybuffer() const +{ + void *buf = nullptr; + size_t bufLen = 0; + bool status = napi_get_arraybuffer_info(env_, val_, &buf, &bufLen); + return make_tuple(status == napi_ok, buf, bufLen); +} + +tuple NVal::ToTypedArray() const +{ + napi_typedarray_type type; + napi_value in_array_buffer = nullptr; + size_t byte_offset; + size_t length; + void *data = nullptr; + napi_status status = + napi_get_typedarray_info(env_, val_, &type, &length, (void **)&data, &in_array_buffer, &byte_offset); + return make_tuple(status == napi_ok, data, length); +} + +bool NVal::HasProp(string propName) const +{ + bool res = false; + + if (!env_ || !val_ || !TypeIs(napi_object)) + return false; + napi_status status = napi_has_named_property(env_, val_, propName.c_str(), &res); + return (status == napi_ok) && res; +} + +NVal NVal::GetProp(string propName) const +{ + if (!HasProp(propName)) { + return { env_, nullptr }; + } + napi_value prop = nullptr; + napi_status status = napi_get_named_property(env_, val_, propName.c_str(), &prop); + if (status != napi_ok) { + return { env_, nullptr }; + } + return NVal(env_, prop); +} + +bool NVal::AddProp(vector &&propVec) const +{ + if (!TypeIs(napi_valuetype::napi_object)) { + ERR_LOG("INNER BUG. Prop should only be added to objects"); + return false; + } + napi_status status = napi_define_properties(env_, val_, propVec.size(), propVec.data()); + if (status != napi_ok) { + ERR_LOG("INNER BUG. Cannot define properties because of %{public}d", status); + return false; + } + return true; +} + +bool NVal::AddProp(string propName, napi_value val) const +{ + if (!TypeIs(napi_valuetype::napi_object) || HasProp(propName)) { + ERR_LOG("INNER BUG. Prop should only be added to objects"); + return false; + } + + napi_status status = napi_set_named_property(env_, val_, propName.c_str(), val); + if (status != napi_ok) { + ERR_LOG("INNER BUG. Cannot set named property because of %{public}d", status); + return false; + } + return true; +} + +NVal NVal::CreateUndefined(napi_env env) +{ + napi_value res = nullptr; + napi_get_undefined(env, &res); + return { env, res }; +} + +NVal NVal::CreateInt32(napi_env env, int32_t val) +{ + napi_value res = nullptr; + napi_create_int32(env, val, &res); + return { env, res }; +} + +NVal NVal::CreateInt64(napi_env env, int64_t val) +{ + napi_value res = nullptr; + napi_create_int64(env, val, &res); + return { env, res }; +} + +NVal NVal::CreateObject(napi_env env) +{ + napi_value res = nullptr; + napi_create_object(env, &res); + return { env, res }; +} + +NVal NVal::CreateBool(napi_env env, bool val) +{ + napi_value res = nullptr; + napi_get_boolean(env, val, &res); + return { env, res }; +} + +NVal NVal::CreateUTF8String(napi_env env, std::string str) +{ + napi_value res = nullptr; + napi_create_string_utf8(env, str.c_str(), str.length(), &res); + return { env, res }; +} + +NVal NVal::CreateUTF8String(napi_env env, const char* str, ssize_t len) +{ + napi_value res = nullptr; + napi_create_string_utf8(env, str, len, &res); + return { env, res }; +} + +NVal NVal::CreateUint8Array(napi_env env, void *buf, size_t bufLen) +{ + napi_value output_buffer = nullptr; + napi_create_external_arraybuffer( + env, + buf, + bufLen, + [](napi_env env, void *finalize_data, void *finalize_hint) { free(finalize_data); }, + NULL, + &output_buffer); + napi_value output_array = nullptr; + napi_create_typedarray(env, napi_uint8_array, bufLen, output_buffer, 0, &output_array); + return { env, output_array }; +} +tuple NVal::CreateArrayBuffer(napi_env env, size_t len) +{ + napi_value val; + void *buf = nullptr; + napi_create_arraybuffer(env, len, &buf, &val); + return { { env, val }, { buf }}; +} + +napi_property_descriptor NVal::DeclareNapiProperty(const char *name, napi_value val) +{ + return { (name), nullptr, nullptr, nullptr, nullptr, val, napi_default, nullptr }; +} + +napi_property_descriptor NVal::DeclareNapiStaticProperty(const char *name, napi_value val) +{ + return { (name), nullptr, nullptr, nullptr, nullptr, val, napi_static, nullptr }; +} + +napi_property_descriptor NVal::DeclareNapiFunction(const char *name, napi_callback func) +{ + return { (name), nullptr, (func), nullptr, nullptr, nullptr, napi_default, nullptr }; +} + +napi_property_descriptor NVal::DeclareNapiStaticFunction(const char *name, napi_callback func) +{ + return { (name), nullptr, (func), nullptr, nullptr, nullptr, napi_static, nullptr }; +} + +napi_property_descriptor NVal::DeclareNapiGetter(const char *name, napi_callback getter) +{ + return { (name), nullptr, nullptr, (getter), nullptr, nullptr, napi_default, nullptr }; +} + +napi_property_descriptor NVal::DeclareNapiSetter(const char *name, napi_callback setter) +{ + return { (name), nullptr, nullptr, nullptr, (setter), nullptr, napi_default, nullptr }; +} + +napi_property_descriptor NVal::DeclareNapiGetterSetter(const char *name, napi_callback getter, napi_callback setter) +{ + return { (name), nullptr, nullptr, (getter), (setter), nullptr, napi_default, nullptr }; +} +} // namespace DistributedFS +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/common/napi/n_val.h b/interfaces/kits/js/src/common/napi/n_val.h new file mode 100644 index 00000000..0cb2f74a --- /dev/null +++ b/interfaces/kits/js/src/common/napi/n_val.h @@ -0,0 +1,79 @@ +/* + * 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. + */ + +#pragma once + +#include +#include +#include + +#include "sys/types.h" +#include "uni_header.h" +namespace OHOS { +namespace DistributedFS { +class NVal final { +public: + NVal() = default; + NVal(napi_env nEnv, napi_value nVal); + NVal &operator = (const NVal &) = default; + virtual ~NVal() = default; + + // NOTE! env_ and val_ is LIKELY to be null + napi_env env_ = nullptr; + napi_value val_ = nullptr; + + explicit operator bool() const; + bool TypeIs(napi_valuetype expType) const; + bool TypeIsError(bool checkErrno = false) const; + + /* SHOULD ONLY BE USED FOR EXPECTED TYPE */ + std::tuple, size_t> ToUTF8String() const; + std::tuple, size_t> ToUTF16String() const; + std::tuple ToPointer() const; + std::tuple ToBool() const; + std::tuple ToInt32() const; + std::tuple ToInt64() const; + std::tuple ToArraybuffer() const; + std::tuple ToTypedArray() const; + + /* Static helpers to create js objects */ + static NVal CreateUndefined(napi_env env); + static NVal CreateInt32(napi_env env, int32_t val); + static NVal CreateInt64(napi_env env, int64_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); + static NVal CreateUTF8String(napi_env env, const char* str, ssize_t len); + static NVal CreateUint8Array(napi_env env, void *buf, size_t bufLen); + static std::tuple CreateArrayBuffer(napi_env env, size_t len); + /* SHOULD ONLY BE USED FOR OBJECT */ + bool HasProp(std::string propName) const; + NVal GetProp(std::string propName) const; + bool AddProp(std::vector &&propVec) const; + bool AddProp(std::string propName, napi_value nVal) const; + + /* Static helpers to create prop of js objects */ + static napi_property_descriptor DeclareNapiProperty(const char *name, napi_value val); + static napi_property_descriptor DeclareNapiStaticProperty(const char *name, napi_value val); + static napi_property_descriptor DeclareNapiFunction(const char *name, napi_callback func); + static napi_property_descriptor DeclareNapiStaticFunction(const char *name, napi_callback func); + static napi_property_descriptor DeclareNapiGetter(const char *name, napi_callback getter); + static napi_property_descriptor DeclareNapiSetter(const char *name, napi_callback setter); + static inline napi_property_descriptor DeclareNapiGetterSetter(const char *name, + napi_callback getter, + napi_callback setter); +}; +} // namespace DistributedFS +} // namespace OHOS diff --git a/interfaces/kits/js/src/common/napi/uni_header.h b/interfaces/kits/js/src/common/napi/uni_header.h new file mode 100644 index 00000000..a79d4e1e --- /dev/null +++ b/interfaces/kits/js/src/common/napi/uni_header.h @@ -0,0 +1,23 @@ +/* + * 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. + */ + +#pragma once + +#ifdef FILE_SUBSYSTEM_DEV_ON_PC +#include +#else +#include "napi/native_api.h" +#include "napi/native_node_api.h" +#endif diff --git a/interfaces/kits/js/src/common/uni_error.cpp b/interfaces/kits/js/src/common/uni_error.cpp new file mode 100644 index 00000000..0f1e0882 --- /dev/null +++ b/interfaces/kits/js/src/common/uni_error.cpp @@ -0,0 +1,122 @@ +/* + * 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 "uni_error.h" + +#include +#include + +#include "log.h" +#include "napi/n_val.h" + +namespace OHOS { +namespace DistributedFS { +using namespace std; + +UniError::UniError() {} + +UniError::UniError(ELegacy eLegacy) : errno_(eLegacy), codingSystem_(ERR_CODE_SYSTEM_LEGACY) {} + +UniError::UniError(int ePosix) : errno_(ePosix), codingSystem_(ERR_CODE_SYSTEM_POSIX) {} + +UniError::operator bool() const +{ + return errno_ != ERRNO_NOERR; +} + +int UniError::GetErrno(ErrCodeSystem cs) +{ + if (errno_ == ERRNO_NOERR) { + return ERRNO_NOERR; + } + if (cs == codingSystem_) { + return errno_; + } + + if (cs == ERR_CODE_SYSTEM_POSIX) { + // Note that we should support more codes here + return EINVAL; + } + + // Note that this shall be done properly + return ELEGACY_INVAL; +} + +void UniError::SetErrno(ELegacy eLegacy) +{ + errno_ = eLegacy; + codingSystem_ = ERR_CODE_SYSTEM_LEGACY; +} + +void UniError::SetErrno(int ePosix) +{ + errno_ = ePosix; + codingSystem_ = ERR_CODE_SYSTEM_POSIX; +} + +std::string UniError::GetDefaultErrstr() +{ + if (codingSystem_ != ERR_CODE_SYSTEM_POSIX && codingSystem_ != ERR_CODE_SYSTEM_LEGACY) { + return "BUG: Curious coding system"; + } + return strerror(GetErrno(ERR_CODE_SYSTEM_POSIX)); +} + +napi_value UniError::GetNapiErr(napi_env env) +{ + return GetNapiErr(env, GetDefaultErrstr()); +} + +napi_value UniError::GetNapiErr(napi_env env, string errMsg) +{ + if (!*this) { + return NVal::CreateUndefined(env).val_; + } + + napi_value code = NVal::CreateUTF8String(env, to_string(GetErrno(codingSystem_))).val_; + napi_value msg = NVal::CreateUTF8String(env, errMsg).val_; + + napi_value res = nullptr; + napi_status createRes = napi_create_error(env, code, msg, &res); + if (createRes) { + ERR_LOG("Failed to create an exception, msg = %{public}s", errMsg.c_str()); + } + return res; +} + +void UniError::ThrowErr(napi_env env) +{ + string msg = GetDefaultErrstr(); + napi_value tmp = nullptr; + napi_get_and_clear_last_exception(env, &tmp); + // Note that ace engine cannot thow errors created by napi_create_error so far + napi_status throwStatus = napi_throw_error(env, nullptr, msg.c_str()); + if (throwStatus != napi_ok) { + ERR_LOG("Failed to throw an exception, %{public}d, code = %{public}s", throwStatus, msg.c_str()); + } +} + +void UniError::ThrowErr(napi_env env, string errMsg) +{ + napi_value tmp = nullptr; + napi_get_and_clear_last_exception(env, &tmp); + // Note that ace engine cannot thow errors created by napi_create_error so far + napi_status throwStatus = napi_throw_error(env, nullptr, errMsg.c_str()); + if (throwStatus != napi_ok) { + ERR_LOG("Failed to throw an exception, %{public}d, code = %{public}s", throwStatus, errMsg.c_str()); + } +} +} // namespace DistributedFS +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/common/uni_error.h b/interfaces/kits/js/src/common/uni_error.h new file mode 100644 index 00000000..a4183986 --- /dev/null +++ b/interfaces/kits/js/src/common/uni_error.h @@ -0,0 +1,64 @@ +/* + * 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. + */ + +#pragma once + +#include +#include + +#include "napi/uni_header.h" + +namespace OHOS { +namespace DistributedFS { +constexpr int ERRNO_NOERR = 0; + +enum ELegacy { + ELEGACY_INVAL = 202, + ELEGACY_IO = 300, + ELEGACY_NOENT = 301, +}; + +enum ErrCodeSystem { + ERR_CODE_SYSTEM_LEGACY, + ERR_CODE_SYSTEM_POSIX, +}; + +class UniError { +public: + UniError(); + explicit UniError(ELegacy eLegacy); + explicit UniError(int ePosix); + ~UniError() = default; + + UniError &operator = (const UniError &) = default; + + explicit operator bool() const; + + void SetErrno(ELegacy eLegacy); + void SetErrno(int ePosix); + int GetErrno(ErrCodeSystem cs); + + std::string GetDefaultErrstr(); + napi_value GetNapiErr(napi_env env); + napi_value GetNapiErr(napi_env env, std::string errMsg); + void ThrowErr(napi_env env); + void ThrowErr(napi_env env, std::string errMsg); + +private: + int errno_ = ERRNO_NOERR; + ErrCodeSystem codingSystem_ = ERR_CODE_SYSTEM_POSIX; +}; +} // namespace DistributedFS +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/fms_napi.cpp b/interfaces/kits/js/src/fms_napi.cpp new file mode 100644 index 00000000..77de6749 --- /dev/null +++ b/interfaces/kits/js/src/fms_napi.cpp @@ -0,0 +1,207 @@ +/* + * 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 "fms_napi.h" + +#include +#include +#include +#include +#include "common/napi/n_func_arg.h" +#include "common/uni_error.h" + +#include "common/napi/n_async/n_async_work_promise.h" +#include "common/napi/n_async/n_async_work_callback.h" +#include "sys/syscall.h" +#define gettid() syscall(__NR_gettid) + +#ifdef FILE_SUBSYSTEM_DEV_ON_PC +#define DEBUG_LOG(fmt, ...) +#endif +#ifndef FILE_SUBSYSTEM_DEV_ON_PC +#include "log.h" +#include "fms_proxy.h" +#include "ifms_client.h" +#endif +namespace OHOS { +namespace DistributedFS { +namespace FMS_NAPI { +using namespace std; +#ifndef FILE_SUBSYSTEM_DEV_ON_PC +using namespace FileManagerService; +#endif +struct AsyncFileInfoArg { + NRef _ref; +#ifndef FILE_SUBSYSTEM_DEV_ON_PC + vector fileRes; +#else + vector res; +#endif + explicit AsyncFileInfoArg(NVal ref) : _ref(ref) {}; + ~AsyncFileInfoArg() = default; +}; + +napi_value FMS_NAPI::CreateFile(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::TWO, NARG_CNT::THREE)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + bool succ = false; + unique_ptr name; + unique_ptr path; + tie(succ, name, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!succ) { + UniError(EINVAL).ThrowErr(env, "Invalid name"); + return nullptr; + } + tie(succ, path, ignore) = NVal(env, funcArg[NARG_POS::SECOND]).ToUTF8String(); + if (!succ) { + UniError(EINVAL).ThrowErr(env, "Invalid path"); + return nullptr; + } + string uri = ""; +#ifndef FILE_SUBSYSTEM_DEV_ON_PC + FileManagerService::IFmsClient::GetFmsInstance()->CreateFile(name.get(), path.get(), uri); +#endif + return NVal::CreateUTF8String(env, uri).val_; +} + +napi_value FMS_NAPI::ListFile(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + + if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::THREE)) { + UniError(EINVAL).ThrowErr(env, "Number of argments unmatched"); + return nullptr; + } + + bool succ = false; + unique_ptr path; + tie(succ, path, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!succ) { + UniError(EINVAL).ThrowErr(env, "Invalid path"); + return nullptr; + } + int64_t offset = 0; + int64_t count = 0; + bool hasOp = false; + // need to check SECOND valid ? + NVal op(env, NVal(env, funcArg[NARG_POS::SECOND]).val_); + if (op.HasProp("offset")) { + tie(succ, offset) = op.GetProp("offset").ToInt64(); + if (!succ) { + UniError(EINVAL).ThrowErr(env, "Invalid option"); + return nullptr; + } + hasOp = true; + } + + if (op.HasProp("count")) { + tie(succ, count) = op.GetProp("count").ToInt64(); + if (!succ) { + UniError(EINVAL).ThrowErr(env, "Invalid option"); + return nullptr; + } + hasOp = true; + } + napi_value fileArr; + napi_create_array(env, &fileArr); + auto arg = make_shared(NVal(env, fileArr)); + auto cbExec = [path = string(path.get()), offset, count, arg, fileArr] (napi_env env) -> UniError { +#ifndef FILE_SUBSYSTEM_DEV_ON_PC + int err = 0; + vector fileRes; + err = FileManagerService::IFmsClient::GetFmsInstance()->ListFile(path, offset, count, fileRes); + arg->fileRes = fileRes; + if (err) { + // need to add specific error + return UniError(EIO); + } +#else + vector resArr = {"name", "path", "type", "size", "added_time", "modified_time"}; + arg->res = resArr; +#endif + + return UniError(ERRNO_NOERR); + }; + + auto cbComplete = [arg](napi_env env, UniError err) -> NVal { +#ifndef FILE_SUBSYSTEM_DEV_ON_PC + for (unsigned int i = 0; i < arg->fileRes.size(); i++) { + NVal obj = NVal::CreateObject(env); + FileManagerService::FileInfo res = arg->fileRes[i]; + obj.AddProp("name", NVal::CreateUTF8String(env, res.GetName()).val_); + obj.AddProp("path", NVal::CreateUTF8String(env, res.GetPath()).val_); + obj.AddProp("type", NVal::CreateUTF8String(env, res.GetType()).val_); + obj.AddProp("size", NVal::CreateInt64(env, res.GetSize()).val_); + obj.AddProp("added_time", NVal::CreateInt64(env, res.GetAdded_Time()).val_); + obj.AddProp("modified_time", NVal::CreateInt64(env, res.GetModified_time()).val_); + napi_set_property(env, arg->_ref.Deref(env).val_, NVal::CreateInt32(env, i).val_, obj.val_); + } +#else + vector resArr = {"name", "path", "type", "size", "added_time", "modified_time"}; + for (unsigned int i = 0; i < resArr.size(); i++) { + NVal obj = NVal::CreateObject(env); + for (auto s : arg->res) { + obj.AddProp(s, NVal::CreateUTF8String(env, s).val_); + } + napi_set_property(env, arg->_ref.Deref(env).val_, NVal::CreateInt32(env, i).val_, obj.val_); + } +#endif + if (err) { + return { env, err.GetNapiErr(env) }; + } else { + return NVal(env, arg->_ref.Deref(env).val_); + } + }; + string procedureName = "ListFile"; + int argc = funcArg.GetArgc(); + NVal thisVar(env, funcArg.GetThisVar()); + if (argc == NARG_CNT::ONE || (argc == NARG_CNT::TWO && hasOp)) { + return NAsyncWorkPromise(env, thisVar).Schedule(procedureName, cbExec, cbComplete).val_; + } else { + int cbIdx = ((hasOp == false) ? NARG_POS::SECOND : NARG_POS::THIRD); + NVal cb(env, funcArg[cbIdx]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureName, cbExec, cbComplete).val_; + } +} + +napi_value FMS_NAPI::mkdir(napi_env env, napi_callback_info info) +{ + return NVal::CreateUndefined(env).val_; +} + +bool FMS_NAPI::Export() +{ + return exports_.AddProp({ + NVal::DeclareNapiFunction("listFile", ListFile), + NVal::DeclareNapiFunction("CreateFile", CreateFile), + NVal::DeclareNapiFunction("mkdir", mkdir), + }); +} + +string FMS_NAPI::GetClassName() +{ + return FMS_NAPI::className_; +} + +FMS_NAPI::FMS_NAPI(napi_env env, napi_value exports) : NExporter(env, exports) {} + +FMS_NAPI::~FMS_NAPI() {} +} // namespace FMS_NAPI +} // namespace DistributedFS +} // namespace OHOS diff --git a/interfaces/kits/js/src/fms_napi.h b/interfaces/kits/js/src/fms_napi.h new file mode 100644 index 00000000..2f5b8aec --- /dev/null +++ b/interfaces/kits/js/src/fms_napi.h @@ -0,0 +1,38 @@ +/* + * 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. + */ + +#pragma once + +#include "common/napi/n_exporter.h" + +namespace OHOS { +namespace DistributedFS { +namespace FMS_NAPI { +class FMS_NAPI final : public NExporter { +public: + inline static const std::string className_ = "__properities__"; + + static napi_value CreateFile(napi_env env, napi_callback_info info); + static napi_value ListFile(napi_env env, napi_callback_info info); + static napi_value mkdir(napi_env env, napi_callback_info info); + bool Export() override; + std::string GetClassName() override; + + FMS_NAPI(napi_env env, napi_value exports); + ~FMS_NAPI() override; +}; +} // namespace FMS_NAPI +} // namespace DistributedFS +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/module.cpp b/interfaces/kits/js/src/module.cpp new file mode 100644 index 00000000..f783e20a --- /dev/null +++ b/interfaces/kits/js/src/module.cpp @@ -0,0 +1,47 @@ +/* + * 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 +#include + +#include "fms_napi.h" +#include "log.h" + +using namespace std; + +namespace OHOS { +namespace DistributedFS { +namespace FMS_NAPI { + +static napi_value Export(napi_env env, napi_value exports) +{ + std::vector> products; + products.emplace_back(make_unique(env, exports)); + + for (auto &&product : products) { + if (!product->Export()) { + ERR_LOG("INNER BUG. Failed to export class %{public}s for module filemanager", product->GetClassName().c_str()); + return nullptr; + } else { + ERR_LOG("Class %{public}s for module filemanager has been exported", product->GetClassName().c_str()); + } + } + return exports; +} + +NAPI_MODULE(filemanager, Export) +} // namespace FMS_NAPI +} // namespace DistributedFS +} // namespace OHOS \ No newline at end of file diff --git a/ohos.build b/ohos.build new file mode 100644 index 00000000..ca16b782 --- /dev/null +++ b/ohos.build @@ -0,0 +1,12 @@ +{ + "subsystem": "storage", + "parts": { + "filemanager": { + "module_list": [ + "//foundation/storage/services:fms", + "//foundation/storage/sa_profile:filemanager_service_sa_profile", + "//foundation/storage/interfaces/kits/js:filemanager" + ] + } + } +} diff --git a/sa_profile/4933.xml b/sa_profile/4933.xml new file mode 100644 index 00000000..216eb6a8 --- /dev/null +++ b/sa_profile/4933.xml @@ -0,0 +1,28 @@ + + + + fms_service + + /system/lib/libfms_server.z.so + + + 4933 + /system/lib/libfms_server.z.so + true + false + 1 + + diff --git a/sa_profile/BUILD.gn b/sa_profile/BUILD.gn new file mode 100644 index 00000000..11b34990 --- /dev/null +++ b/sa_profile/BUILD.gn @@ -0,0 +1,20 @@ +# 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. + +import("//build/ohos/sa_profile/sa_profile.gni") + +ohos_sa_profile("filemanager_service_sa_profile") { + sources = [ "4933.xml" ] + + part_name = "filemanager" +} diff --git a/services/BUILD.gn b/services/BUILD.gn new file mode 100644 index 00000000..a7556ab9 --- /dev/null +++ b/services/BUILD.gn @@ -0,0 +1,87 @@ +# 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. + +import("//build/ohos.gni") +FMS_BASE_DIR = "//foundation/storage/services" + +group("fms") { + deps = [ + ":fms_service.rc", + ":fms_server", + ] +} + +ohos_prebuilt_etc("fms_service.rc") { + if (use_musl) { + source = "etc/fms_service.cfg" + } else { + source = "etc/fms_service.rc" + } + relative_install_dir = "init" + subsystem_name = "storage" + part_name = "filemanager" +} + + +ohos_shared_library("fms_server") { + subsystem_name = "storage" + part_name = "filemanager" + + include_dirs = [ + "$FMS_BASE_DIR/include", + "$FMS_BASE_DIR/src/client", + "$FMS_BASE_DIR/src/server", + "$FMS_BASE_DIR/src/fileoper", + "$FMS_BASE_DIR/include/fileoper", + "//base/hiviewdfx/hilog/interfaces/native/innerkits/include/hilog", + ] + + sources = [ + "src/server/fms_service_stub.cpp", + "src/server/fms_service.cpp", + "src/fileoper/fms_mediafile_oper.cpp", + "src/fileoper/fms_oper_factory.cpp", + "src/client/fms_proxy.cpp", + ] + + deps = [ + "//utils/native/base:utils", + "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog", + "//foundation/multimedia/medialibrary_standard/frameworks/innerkitsimpl/medialibrary_data_ability:medialibrary_data_ability", + "//foundation/aafwk/standard/frameworks/kits/ability/native:abilitykit_native", + "//foundation/aafwk/standard/interfaces/innerkits/base:base", + "//foundation/aafwk/standard/interfaces/innerkits/dataobs_manager:dataobs_manager", + "//foundation/distributedschedule/dmsfwk/interfaces/innerkits/uri:zuri", + ] + cflags = [] + if (target_cpu == "arm") { + cflags += [ "-DBINDER_IPC_32BIT" ] + } + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + "safwk:system_ability_fwk", + "samgr_standard:samgr_proxy", + "aafwk_standard:ability_manager", + "native_appdatamgr:native_appdatafwk", + "native_appdatamgr:native_dataability", + "native_appdatamgr:native_rdb", + ] +} + +# Unittest +group("test") { + testonly = true + + deps = [ "test:test" ] +} diff --git a/services/etc/fms_service.cfg b/services/etc/fms_service.cfg new file mode 100644 index 00000000..705fd897 --- /dev/null +++ b/services/etc/fms_service.cfg @@ -0,0 +1,14 @@ +{ + "jobs" : [{ + "name" : "boot", + "cmds" : [ + "start fms_service" + ] + } + ], + "services" : [{ + "name" : "fms_service", + "path" : ["/system/bin/sa_main", "/system/profile/fms_service.xml"] + } + ] +} diff --git a/services/etc/fms_service.rc b/services/etc/fms_service.rc new file mode 100644 index 00000000..41f1e4d1 --- /dev/null +++ b/services/etc/fms_service.rc @@ -0,0 +1,20 @@ +# 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. + +service fms_service /system/bin/sa_main /system/profile/fms_service.xml + class z_core + seclabel u:r:audiodistributedservice:s0 + +on boot + start fms_service + diff --git a/services/include/fms_const.h b/services/include/fms_const.h new file mode 100644 index 00000000..6c3afd21 --- /dev/null +++ b/services/include/fms_const.h @@ -0,0 +1,36 @@ +/* + * 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. + */ +#pragma once + +#include +namespace OHOS { +namespace FileManagerService { +enum { + FMS_GET_ROOT, + FMS_MEDIA_START, + FMS_MEDIA_MKDIR, + FMS_MEDIA_LISTFILE, + FMS_MEDIA_CREATEFILE, + FMS_MEDIA_END, + FMS_EXTERNAL_START, + FMS_EXTERNAL_END, +}; +const int32_t SUCCESS = 0; +const int32_t FAIL = -1; +const int32_t E_NOEXIST = -2; +const int32_t E_EMPTYFOLDER = -3; + +} // namespace FileManagerService +} // namespace OHOS diff --git a/services/include/log.h b/services/include/log.h new file mode 100644 index 00000000..87bd8a21 --- /dev/null +++ b/services/include/log.h @@ -0,0 +1,78 @@ +/* + * 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. + */ + +#pragma once + +#include +#ifndef FILE_SUBSYSTEM_DEV_ON_PC +#include "hilog/log.h" +#endif + +#undef LOG_DOMAIN +#undef LOG_TAG +#define LOG_DOMAIN 0xD002B00 +#define LOG_TAG "Storage:FMS" + +#define __FILENAME__ (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__) + +#ifndef FILE_SUBSYSTEM_DEV_ON_PC +#ifndef OHOS_DEBUG +#define DECORATOR_HILOG(op, fmt, args...) \ + do { \ + op(LOG_CORE, fmt, ##args); \ + } while (0) +#else +#define DECORATOR_HILOG(op, fmt, args...) \ + do { \ + op(LOG_CORE, "{%s()-%s:%d} " fmt, __FUNCTION__, __FILENAME__, __LINE__, ##args); \ + } while (0) +#endif + +#define DEBUG_LOG(fmt, args...) HILOG_DEBUG(LOG_CORE, "{%{public}s()-%{public}s:%{public}d} " fmt, __FUNCTION__, __FILENAME__, __LINE__, ##args); +#define ERR_LOG(fmt, args...) HILOG_ERROR(LOG_CORE, "{%{public}s()-%{public}s:%{public}d} " fmt, __FUNCTION__, __FILENAME__, __LINE__, ##args); +#define WARNING_LOG(fmt, args...) HILOG_WARN(LOG_CORE, "{%{public}s()-%{public}s:%{public}d} " fmt, __FUNCTION__, __FILENAME__, __LINE__, ##args); +#define INFO_LOG(fmt, args...) HILOG_INFO(LOG_CORE, "{%{public}s()-%{public}s:%{public}d} " fmt, __FUNCTION__, __FILENAME__, __LINE__, ##args); +#define FATAL_LOG(fmt, args...) HILOG_FATAL(LOG_CORE, "{%{public}s()-%{public}s:%{public}d} " fmt, __FUNCTION__, __FILENAME__, __LINE__, ##args); + +#else +#define PCLOG(fmt, ...) \ + do { \ + const std::vector filter = { \ + "{public}", \ + "{private}", \ + }; \ + std::string str____(fmt); \ + for (auto &&pattern : filter) { \ + size_t pos = 0; \ + while (std::string::npos != (pos = str____.find(pattern))) { \ + str____.erase(pos, pattern.length()); \ + } \ + } \ + str____ += "\n"; \ + printf(str____.c_str(), ##__VA_ARGS__); \ + } while (0); + +#define DEBUG_LOG(fmt, ...) PCLOG("%{public}s: " fmt, __func__, ##__VA_ARGS__) +#define INFO_LOG(fmt, ...) PCLOG("%{public}s: " fmt, __func__, ##__VA_ARGS__) +#define WARNING_LOG(fmt, ...) PCLOG("%{public}s: " fmt, __func__, ##__VA_ARGS__) +#define ERR_LOG(fmt, ...) PCLOG("%{public}s: " fmt, __func__, ##__VA_ARGS__) +#define FATAL_LOG(fmt, ...) PCLOG("%{public}s: " fmt, __func__, ##__VA_ARGS__) +#endif + +#define OK 0 +#define INVALID_PARAM (-1) +#define INIT_FAIL (-2) +#define ERR (-3) +#define PERMISSION_DENIED (-4) diff --git a/services/src/client/fms_proxy.cpp b/services/src/client/fms_proxy.cpp new file mode 100644 index 00000000..db9e1cb5 --- /dev/null +++ b/services/src/client/fms_proxy.cpp @@ -0,0 +1,139 @@ +/* + * 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 "fms_proxy.h" + +#include "fms_const.h" +#include "fms_fileinfo.h" +#include "fms_service_stub.h" +#include "log.h" + +using namespace std; + +namespace OHOS { +namespace FileManagerService { +FileManagerProxy::FileManagerProxy(const sptr &impl) + : IRemoteProxy(impl) { } + +IFmsClient *IFmsClient::GetFmsInstance() +{ + auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (samgr == nullptr) { + DEBUG_LOG("samgr object is NULL."); + return nullptr; + } + sptr object = samgr->GetSystemAbility(FILE_MANAGER_SERVICE_ID); + if (object == nullptr) { + DEBUG_LOG("FileManager Service object is NULL."); + return nullptr; + } + static FileManagerProxy msProxy(object); + + DEBUG_LOG("FileManagerProxy::GetFmsInstance"); + return &msProxy; +} + +int FileManagerProxy::CreateFile(string name, string path, string &uri) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + sptr remote = Remote(); + data.WriteString(name); + data.WriteString(path); + int err = remote->SendRequest(FMS_MEDIA_CREATEFILE, data, reply, option); + if (err != ERR_NONE) { + ERR_LOG("FileManagerProxy::CreateFile send request fail %{public}d", err); + return err; + } + reply.ReadString(uri); + DEBUG_LOG("FileManagerProxy::CreateFile reply uri %{public}s", uri.c_str()); + reply.ReadInt32(err); + DEBUG_LOG("FileManagerProxy::CreateFile reply %{public}d", err); + return err; +} + +int GetFileInfo(FileInfo &file, MessageParcel &reply) +{ + string path; + string name; + string type; + int64_t size = 0; + int64_t at = 0; + int64_t mt = 0; + + reply.ReadString(path); + reply.ReadString(type); + reply.ReadString(name); + reply.ReadInt64(size); + reply.ReadInt64(at); + reply.ReadInt64(mt); + file = FileInfo(name, path, type, size, at, mt); + return SUCCESS; +} + + +int FileManagerProxy::ListFile(string path, int off, int count, vector &fileRes) +{ + int err; + MessageParcel data; + MessageParcel reply; + MessageOption option; + + sptr remote = Remote(); + data.WriteString(path); + data.WriteInt32(off); + data.WriteInt32(count); + err = remote->SendRequest(FMS_MEDIA_LISTFILE, data, reply, option); + if (err != ERR_NONE) { + ERR_LOG("FileManagerProxy::ListFile err %{public}d", err); + return err; + } + int fileInfoNum = 0; + reply.ReadInt32(fileInfoNum); + ERR_LOG("FileManagerProxy::ListFile num %{public}d", fileInfoNum); + while (fileInfoNum) { + FileInfo file; + GetFileInfo(file, reply); + fileRes.emplace_back(file); + fileInfoNum--; + } + reply.ReadInt32(err); + DEBUG_LOG("FileManagerProxy::ListFile reply %{public}d", err); + return err; +} + +int FileManagerProxy::mkdir(string name, string path) +{ + int err; + MessageParcel data; + MessageParcel reply; + MessageOption option; + + sptr remote = Remote(); + data.WriteString(name); + data.WriteString(path); + err = remote->SendRequest(FMS_MEDIA_MKDIR, data, reply, option); + if (err != ERR_NONE) { + ERR_LOG("FileManagerProxy::mkdir err %{public}d", err); + return err; + } + reply.ReadInt32(err); + DEBUG_LOG("FileManagerProxy::mkdir reply %{public}d", err); + return err; +} + +} // FileManagerService +} // namespace OHOS \ No newline at end of file diff --git a/services/src/client/fms_proxy.h b/services/src/client/fms_proxy.h new file mode 100644 index 00000000..2b3d6d1b --- /dev/null +++ b/services/src/client/fms_proxy.h @@ -0,0 +1,38 @@ +/* + * 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. + */ +#pragma once + +#include "fms_service_stub.h" +#include "ifms_client.h" +#include "iremote_proxy.h" +#include "iservice_registry.h" +#include "system_ability_definition.h" + +namespace OHOS { +namespace FileManagerService { +class FileManagerProxy : public IRemoteProxy, public IFmsClient { +public: + explicit FileManagerProxy(const sptr &impl); + virtual ~FileManagerProxy() = default; + static IFmsClient* GetFmsInstance(); + int mkdir(std::string name, std::string path); + int ListFile(std::string path, int off, int count, std::vector &fileRes); + int CreateFile(std::string name, std::string path, std::string &uri); + +private: + static inline BrokerDelegator delegator_; +}; +} // namespace FileManagerService +} // namespace OHOS \ No newline at end of file diff --git a/services/src/client/ifms_client.h b/services/src/client/ifms_client.h new file mode 100644 index 00000000..3b50f90f --- /dev/null +++ b/services/src/client/ifms_client.h @@ -0,0 +1,32 @@ +/* + * 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. + */ + +#pragma once +#include "fms_fileinfo.h" + +namespace OHOS { +namespace FileManagerService { +class IFmsClient { +public: + virtual ~IFmsClient() {} + + static IFmsClient *GetFmsInstance(); + + virtual int mkdir(std::string name, std::string path) = 0; + virtual int ListFile(std::string path, int off, int count, std::vector &fileRes) = 0; + virtual int CreateFile(std::string name, std::string path, std::string &uri) = 0; +}; +} // namespace FileManagerService { +} // namespace OHOS \ No newline at end of file diff --git a/services/src/fileoper/fms_file_oper.h b/services/src/fileoper/fms_file_oper.h new file mode 100644 index 00000000..efd32fe5 --- /dev/null +++ b/services/src/fileoper/fms_file_oper.h @@ -0,0 +1,34 @@ +/* + * 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. + */ + +#pragma once + +#include +#include "ipc_types.h" +#include "iremote_broker.h" +#include "iremote_proxy.h" +#include "iremote_stub.h" + +namespace OHOS { +namespace FileManagerService { +class FileOper { +public: + virtual ~FileOper() = default; + virtual int mkdir(const std::string &name, const std::string &path) = 0; + virtual int ListFile(const std::string &path, int offset, int count, MessageParcel &data) = 0; + virtual int CreateFile(const std::string &name, const std::string &path, std::string &uri); +}; +} // OHOS +} // FileManager \ No newline at end of file diff --git a/services/src/fileoper/fms_fileinfo.h b/services/src/fileoper/fms_fileinfo.h new file mode 100644 index 00000000..d5cd9082 --- /dev/null +++ b/services/src/fileoper/fms_fileinfo.h @@ -0,0 +1,66 @@ +/* + * 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. + */ + +#pragma once + +#include +#include +#include "ipc_types.h" +#include "iremote_broker.h" +#include "iremote_proxy.h" +#include "iremote_stub.h" + +namespace OHOS { +namespace FileManagerService { +class FileInfo { +public: + FileInfo() {}; + FileInfo(const std::string &name, const std::string &path, const std::string &type, int64_t size, int64_t added_time, + int64_t modified_time) : path_(path), name_(name), type_(type), size_(size), + added_time_(added_time), modified_time_(modified_time) {} + std::string GetName() + { + return name_; + } + std::string GetPath() + { + return path_; + } + std::string GetType() + { + return type_; + } + int64_t GetSize() + { + return size_; + } + int64_t GetAdded_Time() + { + return added_time_; + } + int64_t GetModified_time() + { + return modified_time_; + } +private: + std::string path_; + std::string name_; + std::string type_; + int64_t size_; + int64_t added_time_; + int64_t modified_time_; +}; +} // OHOS +} // FileManager \ No newline at end of file diff --git a/services/src/fileoper/fms_mediafile_oper.cpp b/services/src/fileoper/fms_mediafile_oper.cpp new file mode 100644 index 00000000..5b10efda --- /dev/null +++ b/services/src/fileoper/fms_mediafile_oper.cpp @@ -0,0 +1,196 @@ +/* + * 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 "fms_mediafile_oper.h" + +#include + +#include "fms_const.h" +#include "fms_fileinfo.h" +#include "ipc_types.h" +#include "iremote_broker.h" +#include "iremote_proxy.h" +#include "iremote_stub.h" +#include "log.h" +#include "media_data_ability_const.h" +#include "medialibrary_data_ability.h" + +using namespace std; + +namespace OHOS { +namespace FileManagerService { +const std::vector mediaData = { Media::MEDIA_DATA_DB_ID, + Media::MEDIA_DATA_DB_URI, + Media::MEDIA_DATA_DB_NAME }; +const std::vector> mediaMetaMap = { {0, "string"}, // 0 id + {1, "string"}, // 1 fileuri + {4, "string"}, // 4 type + {6, "string"}, // 6 name + {7, "int"}, // 7 size + {8, "int"}, // 8 at + {9, "int"} }; // 9 mt +int Insert(const string &name, const string &path, const string &type) +{ + Media::ValuesBucket values; + Media::MediaLibraryDataAbility abi; + string abilityUri = Media::MEDIALIBRARY_DATA_URI; + string oper; + if (type == "album") { + oper = Media::MEDIA_ALBUMOPRN + "/" + Media::MEDIA_ALBUMOPRN_CREATEALBUM; + } else if(type == "file") { + oper = Media::MEDIA_FILEOPRN + "/" + Media::MEDIA_FILEOPRN_CREATEASSET; + } + Uri createUri(abilityUri + "/" + oper); + struct stat statInfo {}; + string str = createUri.ToString(); + DEBUG_LOG("MediaFileOper::Insert uri %{public}s", str.c_str()); + values.PutString(Media::MEDIA_DATA_DB_URI, name); + values.PutString(Media::MEDIA_DATA_DB_FILE_PATH, path + "/" + name); + values.PutString(Media::MEDIA_DATA_DB_RELATIVE_PATH, "dstPath2"); + values.PutString(Media::MEDIA_DATA_DB_NAME, "dispName2"); + values.PutLong(Media::MEDIA_DATA_DB_DATE_ADDED, statInfo.st_ctime); + values.PutLong(Media::MEDIA_DATA_DB_DATE_MODIFIED, statInfo.st_mtime); + abi.InitMediaLibraryRdbStore(); + return abi.Insert(createUri, values); +} + +int MediaFileOper::CreateFile(const std::string &name, const std::string &path, std::string &uri) +{ + string type = "file"; + + int index = Insert(name, path, type); + + // media type need to check the path + if (index < 0) { + ERR_LOG("MediaFileOper:: Fail to create fail %{public}s %{public}s", name.c_str(), path.c_str()); + return index; + } + uri = Media::MEDIALIBRARY_FILE_URI; + uri += "/" + to_string(index); + return SUCCESS; +} + +bool pushFileInfo(shared_ptr result, MessageParcel &reply) +{ + string id; + string uri; + result->GetString(mediaMetaMap[0].first, id); + result->GetString(mediaMetaMap[1].first, uri); + reply.WriteString(uri + "/" + id); + for (int i = 2; i < mediaMetaMap.size(); i++) { + if(mediaMetaMap[i].second == "string") + { + string value; + result->GetString(mediaMetaMap[i].first, value); + reply.WriteString(value); + } else { + int64_t value; + result->GetLong(mediaMetaMap[i].first, value); + reply.WriteInt64(value); + } + } + return true; +} + +int GetFileInfoFromResult(shared_ptr result, MessageParcel &reply) +{ + int count = 0; + result->GetRowCount(count); + if (count == 0) { + ERR_LOG("GetFileInfoFromResult::AbsSharedResultSet null"); + return FAIL; + } + result->GoToFirstRow(); + reply.WriteInt32(count); + for (int i = 0; i < count; i++) { + pushFileInfo(result, reply); + result->GoToNextRow(); + } + return SUCCESS; +} + +bool GetRelativePath(const string &path, string &relativePath) +{ + NativeRdb::DataAbilityPredicates predicates; + string selection = Media::MEDIA_DATA_DB_ID + " LIKE ? "; + vector selectionArgs = { path }; + predicates.SetWhereClause(selection); + predicates.SetWhereArgs(selectionArgs); + Media::MediaLibraryDataAbility abi; + abi.InitMediaLibraryRdbStore(); + Uri uri(Media::MEDIALIBRARY_DATA_URI); + vector columns; + shared_ptr result = abi.Query(uri, columns, predicates); + if (result == nullptr) { + return false; + } + int count = 0; + result->GetRowCount(count); + + if (count != 1) { + ERR_LOG("GetRelativePath::AbsSharedResultSet more than one uri"); + } + int32_t columnIndex; + int ret = result->GetColumnIndex(Media::MEDIA_DATA_DB_FILE_PATH, columnIndex); + if(ret != NativeRdb::E_OK) { + return false; + } + result->GoToFirstRow(); + ret = result->GetString(columnIndex, relativePath); + if(ret != NativeRdb::E_OK) { + return false; + } + DEBUG_LOG("GetRelativePath %{public}s", relativePath.c_str()); + return true; +} + +int MediaFileOper::ListFile(const string &path, int offset, int count, MessageParcel &reply) +{ + //get the relative path from the path uri + string relativePath; + + DEBUG_LOG("ListFile %{public}s", path.c_str()); + if(!GetRelativePath(path, relativePath)) { + ERR_LOG("MediaFileOper::path not exsit"); + return E_NOEXIST; + } + NativeRdb::DataAbilityPredicates predicates; + string selection = Media::MEDIA_DATA_DB_RELATIVE_PATH + " LIKE ? "; + vector selectionArgs = { relativePath }; + predicates.SetWhereClause(selection); + predicates.SetWhereArgs(selectionArgs); + Media::MediaLibraryDataAbility abi; + abi.InitMediaLibraryRdbStore(); + Uri uri(Media::MEDIALIBRARY_DATA_URI); + vector columns; + shared_ptr result = abi.Query(uri, columns, predicates); + if (result == nullptr) { + ERR_LOG("MediaFileOper::ListFile folder is empty"); + return E_EMPTYFOLDER; + } + GetFileInfoFromResult(result, reply); + return SUCCESS; +} + +int MediaFileOper::mkdir(const string &name, const string &path) +{ + string type = "album"; + Insert(name, path, type); + DEBUG_LOG("MediaFileOper::mkdir path %{public}s.", path.c_str()); + return 1; +} + +} // namespace FileManagerService +} // namespace OHOS \ No newline at end of file diff --git a/services/src/fileoper/fms_mediafile_oper.h b/services/src/fileoper/fms_mediafile_oper.h new file mode 100644 index 00000000..5b87b33d --- /dev/null +++ b/services/src/fileoper/fms_mediafile_oper.h @@ -0,0 +1,31 @@ +/* + * 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. + */ + +#pragma once + +#include +#include "fms_file_oper.h" + +namespace OHOS { +namespace FileManagerService { +class MediaFileOper : public FileOper { +public: + virtual ~MediaFileOper() = default; + int mkdir(const std::string &name, const std::string &path) override; + int ListFile(const std::string &path, int offset, int count, MessageParcel &data) override; + int CreateFile(const std::string &name, const std::string &path, std::string &uri) override; +}; +} // OHOS +} // FileManager \ No newline at end of file diff --git a/services/src/fileoper/fms_oper_factory.cpp b/services/src/fileoper/fms_oper_factory.cpp new file mode 100644 index 00000000..1a3658ba --- /dev/null +++ b/services/src/fileoper/fms_oper_factory.cpp @@ -0,0 +1,34 @@ +/* + * 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 "fms_file_oper.h" +#include "fms_mediafile_oper.h" +#include "fms_oper_factory.h" +#include "log.h" + +using namespace std; + +namespace OHOS { +namespace FileManagerService { +FileOper* OperFactory::getFileOper(string oper) +{ + + DEBUG_LOG("OperFactory::getFileOper %{public}s.",oper.c_str()); + + return new MediaFileOper(); +} + +} // namespace FileManagerService +} // namespace OHOS \ No newline at end of file diff --git a/services/src/fileoper/fms_oper_factory.h b/services/src/fileoper/fms_oper_factory.h new file mode 100644 index 00000000..4b4e7bef --- /dev/null +++ b/services/src/fileoper/fms_oper_factory.h @@ -0,0 +1,29 @@ +/* + * 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. + */ + +#pragma once + +#include + +#include "fms_file_oper.h" + +namespace OHOS { +namespace FileManagerService { +class OperFactory { +public: + FileOper* getFileOper(std::string oper); +}; +} // OHOS +} // FileManager \ No newline at end of file diff --git a/services/src/server/fms_service.cpp b/services/src/server/fms_service.cpp new file mode 100644 index 00000000..5e3d14ed --- /dev/null +++ b/services/src/server/fms_service.cpp @@ -0,0 +1,46 @@ +/* + * 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 "fms_service.h" + +#include "iservice_registry.h" +#include "log.h" +#include "system_ability_definition.h" + + +namespace OHOS { +namespace FileManagerService { +REGISTER_SYSTEM_ABILITY_BY_ID(FileManagerService, FILE_MANAGER_SERVICE_ID, true); + +FileManagerService::FileManagerService(int32_t systemAbilityId, bool runOnCreate) + : SystemAbility(systemAbilityId, runOnCreate) { } +void FileManagerService::OnDump() { } + +void FileManagerService::OnStart() +{ + DEBUG_LOG("FileManagerService::OnStart called"); + bool res = Publish(this); + if (res) { + DEBUG_LOG("FileManagerService OnStart valid"); + } +} + +void FileManagerService::OnStop() +{ + DEBUG_LOG("FileManagerService OnStop"); +} + +} // namespace FileManagerService +} // namespace OHOS \ No newline at end of file diff --git a/services/src/server/fms_service.h b/services/src/server/fms_service.h new file mode 100644 index 00000000..6ae6679f --- /dev/null +++ b/services/src/server/fms_service.h @@ -0,0 +1,41 @@ +/* + * 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. + */ + +#pragma once + +#include "iremote_stub.h" +#include "system_ability.h" +#include "fms_service_stub.h" + +namespace OHOS { +namespace FileManagerService { + +class FileManagerService : public SystemAbility, public FileManagerServiceStub { + DECLARE_SYSTEM_ABILITY(FileManagerService); +public: + DISALLOW_COPY_AND_MOVE(FileManagerService); + explicit FileManagerService(int32_t systemAbilityId, bool runOnCreate = true); + virtual ~FileManagerService() = default; + + void OnDump() override; + + void OnStart() override; + + void OnStop() override; + +}; + +} // namespace FileManagerService +} // namespace OHOS diff --git a/services/src/server/fms_service_stub.cpp b/services/src/server/fms_service_stub.cpp new file mode 100644 index 00000000..a3c15044 --- /dev/null +++ b/services/src/server/fms_service_stub.cpp @@ -0,0 +1,110 @@ +/* + * 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 "fms_service_stub.h" + +#include "fms_const.h" +#include "fms_oper_factory.h" +#include "fms_service.h" +#include "log.h" + +using namespace std; + +namespace OHOS { +namespace FileManagerService { +int FileManagerServiceStub::OperMediaProcess(OperFactory &factory, uint32_t code, MessageParcel &data, + MessageParcel &reply) +{ + int errCode = SUCCESS; + if (code < FMS_MEDIA_START || code > FMS_MEDIA_END) { + return errCode; + } + auto *fp = factory.getFileOper("media"); + // media process + switch(code) { + case FMS_MEDIA_MKDIR: { + string name = data.ReadString(); + string path = data.ReadString(); + errCode = fp->mkdir(name, path); + break; + } + case FMS_MEDIA_LISTFILE: { + string path = data.ReadString(); + int off = data.ReadInt32(); + int count = data.ReadInt32(); + errCode = fp->ListFile(path, off, count, reply); + // need reply fileInfo + break; + } + case FMS_MEDIA_CREATEFILE: { + string name = data.ReadString(); + string path = data.ReadString(); + string uri; + errCode = fp->CreateFile(name, path, uri); + reply.WriteString(uri); + break; + } + default: + break; + } + delete fp; + return errCode; +} + +int FileManagerServiceStub::OperExtProcess(OperFactory &factory, uint32_t code, MessageParcel &data, + MessageParcel &reply) +{ + int errCode = SUCCESS; + if (code < FMS_EXTERNAL_START || code > FMS_EXTERNAL_END) { + return errCode; + } + // do Exteranl storage process; + return errCode; +} + +int FileManagerServiceStub::OperProcess(uint32_t code, MessageParcel &data, + MessageParcel &reply) +{ + int errCode = SUCCESS; + + switch (code) { + case FMS_GET_ROOT: { + // return root base on type + // return fileInfo + break; + } + default: { + OperFactory factory = OperFactory(); + // check uri -->Media or --> External + errCode = OperMediaProcess(factory, code, data, reply); + } + } + return errCode; +} + +int FileManagerServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, + MessageParcel &reply, MessageOption &option) +{ + DEBUG_LOG("OnRemoteRequest %{public}d", code); + + // to do checkpermission() + // do file process + int32_t errCode = OperProcess(code, data, reply); + reply.WriteInt32(errCode); + return errCode; +} + +} // namespace FileManagerService +} // namespace OHOS \ No newline at end of file diff --git a/services/src/server/fms_service_stub.h b/services/src/server/fms_service_stub.h new file mode 100644 index 00000000..cdc025c6 --- /dev/null +++ b/services/src/server/fms_service_stub.h @@ -0,0 +1,46 @@ +/* + * 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. + */ + +#pragma once + +#include "ipc_types.h" +#include "iremote_broker.h" +#include "iremote_proxy.h" +#include "iremote_stub.h" +#include "../fileoper/fms_oper_factory.h" + + +namespace OHOS { +namespace FileManagerService { +class IFileManagerService : public IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"IFileManagerService"); +}; + +class FileManagerServiceStub : public IRemoteStub { +public: + + int OperProcess(uint32_t code, MessageParcel &data, MessageParcel &reply); + int OperMediaProcess(OperFactory &factory, uint32_t code, MessageParcel &data, + MessageParcel &reply); + int OperExtProcess(OperFactory &factory, uint32_t code, MessageParcel &data, + MessageParcel &reply); + + virtual int OnRemoteRequest(uint32_t code, MessageParcel &data, + MessageParcel &reply, MessageOption &option) override; +}; + +} // namespace FileManagerService +} // namespace OHOS diff --git a/services/test/BUILD.gn b/services/test/BUILD.gn new file mode 100644 index 00000000..ae241dfe --- /dev/null +++ b/services/test/BUILD.gn @@ -0,0 +1,52 @@ +# 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. + + +import("//build/test.gni") +FMS_BASE_DIR = "//foundation/storage/services" +ohos_unittest("fms_test") { + module_out_path = "storage/fms" + + sources = [ "fms_test.cpp" ] + + include_dirs = [ + "//third_party/json/include", + "//base/security/huks/interfaces/innerkits/huks_standard/main/include", + "$FMS_BASE_DIR/include", + "$FMS_BASE_DIR/src/client", + "$FMS_BASE_DIR/src/server", + ] + + configs = [ + "//build/config/compiler:exceptions", + ] + + deps = [ + "//foundation/storage/services:fms_server", + "//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy", + "//utils/native/base:utils", + ] + + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + "safwk:system_ability_fwk", + "samgr_standard:samgr_proxy", + ] +} + +group("test") { + testonly = true + + deps = [ ":fms_test" ] +} diff --git a/services/test/fms_test.cpp b/services/test/fms_test.cpp new file mode 100644 index 00000000..fb68aa70 --- /dev/null +++ b/services/test/fms_test.cpp @@ -0,0 +1,57 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include "fms_proxy.h" + +namespace { +using namespace std; +using namespace OHOS; +class FMSTest : public testing::Test { +public: + static void SetUpTestCase(void) + { + cout << "FMS code test" << endl; + } + static void TearDownTestCase() {} +}; + +/** + * @tc.number SUB_STORAGE_FMS_Function_Enable_0000 + * @tc.name FMS_Function_Enable_0000 + * @tc.desc Test function of Enable interface. + */ +HWTEST_F(FMSTest, FMS_Function_Enable_0000, testing::ext::TestSize.Level1) +{ + cout << "FMSTest-begin FMS_Function_Enable_0000" << endl; + try { + int result = 0; + FileManagerService::FileManagerProxy proxy; + EXPECT_EQ(result, 0); + } catch (...) { + cout << "FMSTest-an exception occurred." << endl; + } + cout << "FMSTest-end FMS_Function_Enable_0000" << endl; +} + +} // namespace