From 5a814bc71b71c753e0213e596a2b7a257a55893e Mon Sep 17 00:00:00 2001 From: libuyan Date: Fri, 19 Apr 2024 17:42:04 +0800 Subject: [PATCH 01/13] Add Download Picker Signed-off-by: libuyan --- bundle.json | 1 + interfaces/kits/picker/BUILD.gn | 31 ++- .../kits/picker/include/modal_ui_callback.h | 46 ++++ interfaces/kits/picker/include/napi_error.h | 39 +++ .../kits/picker/include/picker_client_errno.h | 83 ++++++ .../kits/picker/include/picker_n_exporter.h | 75 ++++++ .../kits/picker/include/picker_napi_utils.h | 247 ++++++++++++++++++ .../kits/picker/native_module_ohos_picker.cpp | 21 +- interfaces/kits/picker/picker.js | 69 +++++ .../kits/picker/src/modal_ui_callback.cpp | 66 +++++ interfaces/kits/picker/src/napi_error.cpp | 70 +++++ .../kits/picker/src/picker_n_exporter.cpp | 233 +++++++++++++++++ .../kits/picker/src/picker_napi_utils.cpp | 158 +++++++++++ 13 files changed, 1135 insertions(+), 4 deletions(-) create mode 100644 interfaces/kits/picker/include/modal_ui_callback.h create mode 100644 interfaces/kits/picker/include/napi_error.h create mode 100644 interfaces/kits/picker/include/picker_client_errno.h create mode 100644 interfaces/kits/picker/include/picker_n_exporter.h create mode 100644 interfaces/kits/picker/include/picker_napi_utils.h create mode 100644 interfaces/kits/picker/src/modal_ui_callback.cpp create mode 100644 interfaces/kits/picker/src/napi_error.cpp create mode 100644 interfaces/kits/picker/src/picker_n_exporter.cpp create mode 100644 interfaces/kits/picker/src/picker_napi_utils.cpp diff --git a/bundle.json b/bundle.json index e9e6c635..450283ee 100644 --- a/bundle.json +++ b/bundle.json @@ -25,6 +25,7 @@ "components": [ "ability_base", "ability_runtime", + "ace_engine", "app_file_service", "ipc", "init", diff --git a/interfaces/kits/picker/BUILD.gn b/interfaces/kits/picker/BUILD.gn index fa0434b0..0c8963f2 100644 --- a/interfaces/kits/picker/BUILD.gn +++ b/interfaces/kits/picker/BUILD.gn @@ -12,8 +12,11 @@ # limitations under the License. import("//build/ohos.gni") +import("//build/ohos/ace/ace.gni") +import("//foundation/ability/ability_runtime/ability_runtime.gni") import("../../../../../../arkcompiler/ets_frontend/es2panda/es2abc_config.gni") import("../../../filemanagement_aafwk.gni") +import("../../../../../../foundation/arkui/ace_engine/ace_config.gni") # compile .js to .abc. action("gen_picker_abc") { @@ -54,7 +57,18 @@ gen_js_obj("picker_abc") { ohos_shared_library("picker") { branch_protector_ret = "pac_ret" ldflags = [ "-Wl" ] - sources = [ "native_module_ohos_picker.cpp" ] + + include_dirs = [ + "include", + ] + + sources = [ + "native_module_ohos_picker.cpp", + "src/modal_ui_callback.cpp", + "src/picker_n_exporter.cpp", + "src/picker_napi_utils.cpp", + "src/napi_error.cpp", + ] deps = [ ":picker_abc", @@ -62,8 +76,23 @@ ohos_shared_library("picker") { ] external_deps = [ + "ability_base:want", + "ability_base:zuri", + "ability_runtime:ability_context_native", + "ability_runtime:ability_manager", + "ability_runtime:abilitykit_native", + "ability_runtime:app_context", + "ability_runtime:dataobs_manager", + "ability_runtime:napi_base_context", + "ability_runtime:runtime", + "ability_runtime:service_extension", + "ability_runtime:ui_extension", "ability_runtime:abilitykit_native", "napi:ace_napi", + "file_api:filemgmt_libhilog", + "file_api:filemgmt_libn", + "ace_engine:ace_uicontent", + "hilog:libhilog", ] sanitize = { diff --git a/interfaces/kits/picker/include/modal_ui_callback.h b/interfaces/kits/picker/include/modal_ui_callback.h new file mode 100644 index 00000000..d7ecd71d --- /dev/null +++ b/interfaces/kits/picker/include/modal_ui_callback.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef INTERFACES_KITS_JS_PICKER_INCLUDE_MODAL_UI_CALLBACK_H +#define INTERFACES_KITS_JS_PICKER_INCLUDE_MODAL_UI_CALLBACK_H + +#include "ability_context.h" +#include "want.h" +#include "want_params.h" +#include +#include "picker_n_exporter.h" +#include "ui_content.h" + +namespace OHOS { +namespace Picker { + +class ModalUICallback { +public: + explicit ModalUICallback(Ace::UIContent* uiContent, PickerCallBack* pickerCallBack); + void OnRelease(int32_t releaseCode); + void OnResultForModal(int32_t resultCode, const OHOS::AAFwk::Want& result); + void OnReceive(const OHOS::AAFwk::WantParams& request); + void OnError(int32_t code, const std::string& name, const std::string& message); + void OnDestroy(); + void SetSessionId(int32_t sessionId); + +private: + int32_t sessionId_ = 0; + Ace::UIContent* uiContent; + PickerCallBack* pickerCallBack_; +}; +} // namespace Picker +} // namespace OHOS + +#endif \ No newline at end of file diff --git a/interfaces/kits/picker/include/napi_error.h b/interfaces/kits/picker/include/napi_error.h new file mode 100644 index 00000000..e267d562 --- /dev/null +++ b/interfaces/kits/picker/include/napi_error.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INTERFACES_KITS_JS_PICKER_INCLUDE_NAPI_ERROR_H_ +#define INTERFACES_KITS_JS_PICKER_INCLUDE_NAPI_ERROR_H_ + +#include +#include "napi/native_api.h" +#include "napi/native_node_api.h" +#include "picker_napi_utils.h" + +namespace OHOS { +namespace Picker { +#define EXPORT __attribute__ ((visibility ("default"))) +struct NapiError { + int32_t error = 0; + std::string apiName; + void SetApiName(const std::string &Name); + void SaveError(int32_t ret); + void HandleError(napi_env env, napi_value &errorObj); + EXPORT static void ThrowError(napi_env env, int32_t err, const std::string &errMsg = ""); + EXPORT static void ThrowError(napi_env env, int32_t err, const char *func, int32_t line, + const std::string &errMsg = ""); +}; +} // namespace Picker +} // namespace OHOS +#endif // INTERFACES_KITS_JS_PICKER_INCLUDE_NAPI_ERROR_H_ \ No newline at end of file diff --git a/interfaces/kits/picker/include/picker_client_errno.h b/interfaces/kits/picker/include/picker_client_errno.h new file mode 100644 index 00000000..5153b885 --- /dev/null +++ b/interfaces/kits/picker/include/picker_client_errno.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_PICKER_CLIENT_ERRNO_H +#define OHOS_PICKER_CLIENT_ERRNO_H + +#include +#include + + +namespace OHOS { +namespace Picker { +constexpr int32_t FILEIO_MODULE_CODE = 139; +constexpr int32_t UFM_MODULE_CODE = 140; +constexpr int32_t UFM_SYSCAP_BASE = 202; + +constexpr int32_t OHOS_PERMISSION_DENIED_CODE = 201; +constexpr int32_t OHOS_INVALID_PARAM_CODE = 401; + +#define MODULE_OFFSET 100000 +#define MODULE_CODE(code) (((code) * MODULE_OFFSET)) +#define UFM_JS_ERR(moduleCode, errCode) ((MODULE_CODE(moduleCode)) + (errCode)) + +//JS_INNER_FAIL JS_ERR_PARAMETER_INVALID +// file io common error code +constexpr int32_t JS_ERR_NO_SUCH_FILE = UFM_JS_ERR(FILEIO_MODULE_CODE, 2); // no such file +constexpr int32_t JS_ERR_NO_MEM = UFM_JS_ERR(FILEIO_MODULE_CODE, 11); // cannot allocate memory +constexpr int32_t JS_ERR_PERMISSION_DENIED = UFM_JS_ERR(FILEIO_MODULE_CODE, 12); // permission deny +constexpr int32_t JS_ERR_FILE_EXIST = UFM_JS_ERR(FILEIO_MODULE_CODE, 15); // file has exist +constexpr int32_t JS_ERR_PARAMETER_INVALID = UFM_JS_ERR(FILEIO_MODULE_CODE, 20); // input parameter invalid + +// userfileMananger error code +constexpr int32_t JS_E_DISPLAYNAME = UFM_JS_ERR(UFM_MODULE_CODE, 1); +constexpr int32_t JS_E_URI = UFM_JS_ERR(UFM_MODULE_CODE, 2); +constexpr int32_t JS_E_FILE_EXTENSION = UFM_JS_ERR(UFM_MODULE_CODE, 3); +constexpr int32_t JS_E_TRASHED = UFM_JS_ERR(UFM_MODULE_CODE, 4); +constexpr int32_t JS_E_OPEN_MODE = UFM_JS_ERR(UFM_MODULE_CODE, 5); +constexpr int32_t JS_E_NOT_ALBUM = UFM_JS_ERR(UFM_MODULE_CODE, 6); +constexpr int32_t JS_E_ROOT_DIR = UFM_JS_ERR(UFM_MODULE_CODE, 7); +constexpr int32_t JS_E_MOVE_DENIED = UFM_JS_ERR(UFM_MODULE_CODE, 8); +constexpr int32_t JS_E_RENAME_DENIED = UFM_JS_ERR(UFM_MODULE_CODE, 9); +constexpr int32_t JS_E_RELATIVEPATH = UFM_JS_ERR(UFM_MODULE_CODE, 10); +constexpr int32_t JS_INNER_FAIL = UFM_JS_ERR(UFM_MODULE_CODE, 11); +// file type is not allow in the directory +constexpr int32_t JS_E_FILE_TYPE = UFM_JS_ERR(UFM_MODULE_CODE, 12); +constexpr int32_t JS_E_NO_MEMORY = UFM_JS_ERR(UFM_MODULE_CODE, 13); // no memory left +constexpr int32_t JS_E_FILE_KEY = UFM_JS_ERR(UFM_MODULE_CODE, 14); // wrong member name +constexpr int32_t JS_E_INPUT = UFM_JS_ERR(UFM_MODULE_CODE, 15); +// media change request error +constexpr int32_t JS_E_OPERATION_NOT_SUPPORT = UFM_JS_ERR(UFM_MODULE_CODE, 16); +constexpr int32_t JS_E_NAMETOOLONG = UFM_JS_ERR(UFM_SYSCAP_BASE, 36); + +const std::unordered_map jsErrMap = { + { JS_ERR_PERMISSION_DENIED, "without permission" }, + { JS_INNER_FAIL, "medialibrary inner fail" }, + { JS_ERR_PARAMETER_INVALID, "invalid parameter" }, + { JS_E_DISPLAYNAME, "display name invalid" }, + { JS_ERR_NO_SUCH_FILE, "no such file" }, + { JS_ERR_FILE_EXIST, "file has existed" }, + { JS_E_FILE_TYPE, "file type is not allow in the directory" }, + { JS_E_FILE_KEY, "member not exist" }, + { JS_ERR_NO_MEM, "cannot allocate memory" }, + { JS_E_NAMETOOLONG, "file name is too long" }, + { OHOS_PERMISSION_DENIED_CODE, "Permission denied" }, + { OHOS_INVALID_PARAM_CODE, "invalid parameter" }, +}; +} // namespace Picker +} // namespace OHOS + + +#endif // OHOS_PICKER_CLIENT_ERRNO_H diff --git a/interfaces/kits/picker/include/picker_n_exporter.h b/interfaces/kits/picker/include/picker_n_exporter.h new file mode 100644 index 00000000..dc821db9 --- /dev/null +++ b/interfaces/kits/picker/include/picker_n_exporter.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef INTERFACES_KITS_NATIVE_PICKER_N_EXPOTER_H +#define INTERFACES_KITS_NATIVE_PICKER_N_EXPOTER_H + +#include +#include "data_ability_helper.h" +#include "data_ability_observer_stub.h" +#include "data_ability_predicates.h" +#include "filemgmt_libn.h" +#include "picker_napi_utils.h" +#include "napi_error.h" +#include "napi_base_context.h" +#include "napi_common_want.h" +#include "picker_client_errno.h" + + +namespace OHOS { +namespace Picker { +using namespace FileManagement::LibN; +using namespace std; + +struct NameListArg { + struct dirent** namelist = { nullptr }; + int direntNum = 0; +}; + +// 对齐todo: 返回值的内容需要對齊 +struct PickerCallBack { + bool ready = false; + bool isOrigin; + int32_t resultCode; + string uri; +}; + +// 对齐todo:定制上下文内容 +struct PickerAsyncContext : public NapiError { + napi_async_work work; + napi_deferred deferred; + napi_ref callbackRef; + size_t argc; + napi_value argv[NAPI_ARGC_MAX]; + std::shared_ptr pickerCallBack; +}; + +class PickerNExporter final : public FileManagement::LibN::NExporter { +public: + inline static const std::string className_ = "Picker"; + static napi_value StartDownloadPicker(napi_env env, napi_callback_info info); + bool Export() override; + std::string GetClassName() override; + PickerNExporter(napi_env env, napi_value exports); + ~PickerNExporter() override; +}; + +// const std::string RECENT_PATH = "/storage/Users/.Recent/"; +const std::string FILE_ACCESS_PERMISSION = "ohos.permission.FILE_ACCESS_MANAGER"; +constexpr int BUF_SIZE = 1024; +constexpr int MAX_RECENT_SIZE = 100; +static thread_local napi_ref sConstructor_; +} // namespace FileAccessFwk +} // namespace OHOS +#endif // INTERFACES_KITS_NATIVE_PICKER_N_EXPOTER_H diff --git a/interfaces/kits/picker/include/picker_napi_utils.h b/interfaces/kits/picker/include/picker_napi_utils.h new file mode 100644 index 00000000..ccdd5c94 --- /dev/null +++ b/interfaces/kits/picker/include/picker_napi_utils.h @@ -0,0 +1,247 @@ +/* + * Copyright (C) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INTERFACES_KITS_JS_PICKER_INCLUDE_PICKER_NAPI_UTILS_H_ +#define INTERFACES_KITS_JS_PICKER_INCLUDE_PICKER_NAPI_UTILS_H_ + +#include +#include +#include "napi/native_api.h" +#include "napi/native_node_api.h" +#include "hilog_wrapper.h" +#include "picker_client_errno.h" + +#ifdef NAPI_ASSERT +#undef NAPI_ASSERT +#endif + +#define CHECK_ARGS_WITH_MESSAGE(env, cond, msg) \ + do { \ + if (!(cond)) { \ + NapiError::ThrowError(env, JS_ERR_PARAMETER_INVALID, __FUNCTION__, __LINE__, msg); \ + return nullptr; \ + } \ + } while (0) + +#define CHECK_COND_WITH_MESSAGE(env, cond, msg) \ + do { \ + if (!(cond)) { \ + NapiError::ThrowError(env, OHOS_INVALID_PARAM_CODE, __FUNCTION__, __LINE__, msg); \ + return nullptr; \ + } \ + } while (0) + +#define NAPI_ASSERT(env, cond, msg) CHECK_ARGS_WITH_MESSAGE(env, cond, msg) + +#define GET_JS_ARGS(env, info, argc, argv, thisVar) \ + do { \ + void *data; \ + napi_get_cb_info(env, info, &(argc), argv, &(thisVar), &(data)); \ + } while (0) + +#define GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar) \ + do { \ + void *data; \ + status = napi_get_cb_info(env, info, nullptr, nullptr, &(thisVar), &(data)); \ + } while (0) + +#define GET_JS_ASYNC_CB_REF(env, arg, count, cbRef) \ + do { \ + napi_valuetype valueType = napi_undefined; \ + if ((napi_typeof(env, arg, &valueType) == napi_ok) && (valueType == napi_function)) { \ + napi_create_reference(env, arg, count, &(cbRef)); \ + } else { \ + HILOG_ERROR("invalid arguments"); \ + NAPI_ASSERT(env, false, "type mismatch"); \ + } \ + } while (0) + +#define ASSERT_NULLPTR_CHECK(env, result) \ + do { \ + if ((result) == nullptr) { \ + napi_get_undefined(env, &(result)); \ + return result; \ + } \ + } while (0) + +#define NAPI_CREATE_PROMISE(env, callbackRef, deferred, result) \ + do { \ + if ((callbackRef) == nullptr) { \ + napi_create_promise(env, &(deferred), &(result)); \ + } \ + } while (0) + +#define NAPI_CREATE_RESOURCE_NAME(env, resource, resourceName, context) \ + do { \ + napi_create_string_utf8(env, resourceName, NAPI_AUTO_LENGTH, &(resource)); \ + (context)->SetApiName(resourceName); \ + } while (0) + +#define CHECK_NULL_PTR_RETURN_UNDEFINED(env, ptr, ret, message) \ + do { \ + if ((ptr) == nullptr) { \ + HILOG_ERROR(message); \ + napi_get_undefined(env, &(ret)); \ + return ret; \ + } \ + } while (0) + +#define CHECK_NULL_PTR_RETURN_VOID(ptr, message) \ + do { \ + if ((ptr) == nullptr) { \ + HILOG_ERROR(message); \ + return; \ + } \ + } while (0) +#define CHECK_IF_EQUAL(condition, errMsg) \ + do { \ + if (!(condition)) { \ + HILOG_ERROR(errMsg); \ + return; \ + } \ + } while (0) + +#define CHECK_COND_RET(cond, ret, message) \ + do { \ + if (!(cond)) { \ + HILOG_ERROR(message); \ + return ret; \ + } \ + } while (0) + +#define CHECK_STATUS_RET(cond, message) \ + do { \ + napi_status __ret = (cond); \ + if (__ret != napi_ok) { \ + HILOG_ERROR(message); \ + return __ret; \ + } \ + } while (0) + +#define CHECK_NULLPTR_RET(ret) \ + do { \ + if ((ret) == nullptr) { \ + return nullptr; \ + } \ + } while (0) + +#define CHECK_ARGS_BASE(env, cond, err, retVal) \ + do { \ + if ((cond) != napi_ok) { \ + NapiError::ThrowError(env, err, __FUNCTION__, __LINE__); \ + return retVal; \ + } \ + } while (0) + +#define CHECK_ARGS(env, cond, err) CHECK_ARGS_BASE(env, cond, err, nullptr) + +#define CHECK_ARGS_THROW_INVALID_PARAM(env, cond) CHECK_ARGS(env, cond, OHOS_INVALID_PARAM_CODE) + +#define CHECK_ARGS_RET_VOID(env, cond, err) CHECK_ARGS_BASE(env, cond, err, NAPI_RETVAL_NOTHING) + +#define CHECK_COND(env, cond, err) \ + do { \ + if (!(cond)) { \ + NapiError::ThrowError(env, err, __FUNCTION__, __LINE__); \ + return nullptr; \ + } \ + } while (0) + +#define RETURN_NAPI_TRUE(env) \ + do { \ + napi_value result = nullptr; \ + CHECK_ARGS(env, napi_get_boolean(env, true, &result), JS_INNER_FAIL); \ + return result; \ + } while (0) + +#define RETURN_NAPI_UNDEFINED(env) \ + do { \ + napi_value result = nullptr; \ + CHECK_ARGS(env, napi_get_undefined(env, &result), JS_INNER_FAIL); \ + return result; \ + } while (0) + +namespace OHOS { +namespace Picker { +/* Constants for array index */ +const int32_t PARAM0 = 0; +const int32_t PARAM1 = 1; +const int32_t PARAM2 = 2; +const int32_t PARAM3 = 3; +const int32_t PARAM4 = 4; + +/* Constants for array size */ +const int32_t ARGS_ZERO = 0; +const int32_t ARGS_ONE = 1; +const int32_t ARGS_TWO = 2; +const int32_t ARGS_THREE = 3; +const int32_t ARGS_FOUR = 4; +const int32_t ARGS_FIVE = 5; +const int32_t ARG_BUF_SIZE = 384; // 256 for display name and 128 for relative path +constexpr uint32_t NAPI_INIT_REF_COUNT = 1; + +constexpr size_t NAPI_ARGC_MAX = 5; + +// Error codes +const int32_t ERR_DEFAULT = 0; +const int32_t ERR_MEM_ALLOCATION = 2; +const int32_t ERR_INVALID_OUTPUT = 3; + +const int32_t TRASH_SMART_ALBUM_ID = 1; +const std::string TRASH_SMART_ALBUM_NAME = "TrashAlbum"; +const int32_t FAVORIT_SMART_ALBUM_ID = 2; +const std::string FAVORIT_SMART_ALBUM_NAME = "FavoritAlbum"; + +const std::string API_VERSION = "api_version"; + +const std::string PENDING_STATUS = "pending"; + +struct JSAsyncContextOutput { + napi_value error; + napi_value data; + bool status; +}; + +struct NapiClassInfo { + std::string name; + napi_ref *ref; + napi_value (*constructor)(napi_env, napi_callback_info); + std::vector props; +}; + +/* Util class used by napi asynchronous methods for making call to js callback function */ +class PickerNapiUtils { +public: + static int TransErrorCode(const std::string &Name, int error); + static void HandleError(napi_env env, int error, napi_value &errorObj, const std::string &Name); + static void CreateNapiErrorObject(napi_env env, napi_value &errorObj, const int32_t errCode, + const std::string errMsg); + template + static napi_status GetParamCallback(napi_env env, AsyncContext &context); + static napi_status HasCallback(napi_env env, const size_t argc, const napi_value argv[], + bool &isCallback); + static napi_status GetParamFunction(napi_env env, napi_value arg, napi_ref &callbackRef); + static void InvokeJSAsyncMethod(napi_env env, napi_deferred deferred, napi_ref callbackRef, napi_async_work work, + const JSAsyncContextOutput &asyncContext); + template + static napi_value NapiCreateAsyncWork(napi_env env, std::unique_ptr &asyncContext, + const std::string &resourceName, void (*execute)(napi_env, void *), + void (*complete)(napi_env, napi_status, void *)); +}; + +} // namespace Picker +} // namespace OHOS + +#endif // INTERFACES_KITS_JS_PICKER_INCLUDE_PICKER_NAPI_UTILS_H_ diff --git a/interfaces/kits/picker/native_module_ohos_picker.cpp b/interfaces/kits/picker/native_module_ohos_picker.cpp index ba51922b..8547fc81 100644 --- a/interfaces/kits/picker/native_module_ohos_picker.cpp +++ b/interfaces/kits/picker/native_module_ohos_picker.cpp @@ -15,6 +15,7 @@ #include "napi/native_api.h" #include "napi/native_node_api.h" +#include "picker_n_exporter.h" extern const char _binary_picker_js_start[]; extern const char _binary_picker_js_end[]; @@ -23,13 +24,27 @@ extern const char _binary_picker_abc_end[]; namespace OHOS { namespace FileAccessFwk { -/* - * Function registering all props and functions of ohos.medialibrary module - */ +using namespace Picker; +using namespace FileManagement::LibN; + +EXTERN_C_START static napi_value Export(napi_env env, napi_value exports) { + std::vector> products; + products.emplace_back(make_unique(env, exports)); + + for (auto &&product : products) { + std::string nExporterName = product->GetClassName(); + if (!product->Export()) { + HILOG_ERROR("INNER BUG. Failed to export class %{public}s for module trash", nExporterName.c_str()); + return nullptr; + } else { + HILOG_INFO("Class %{public}s for module trash has been exported", nExporterName.c_str()); + } + } return exports; } +EXTERN_C_END extern "C" __attribute__((visibility("default"))) void NAPI_file_picker_GetJSCode(const char** buf, int* bufLen) diff --git a/interfaces/kits/picker/picker.js b/interfaces/kits/picker/picker.js index d5b451d5..b88f48ce 100644 --- a/interfaces/kits/picker/picker.js +++ b/interfaces/kits/picker/picker.js @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +const pickerHelper = requireInternal('file.picker'); const PhotoViewMIMETypes = { IMAGE_TYPE: 'image/*', @@ -26,6 +27,11 @@ const DocumentSelectMode = { MIXED: 2, }; +const DocumentSaveMode = { + DEFAULT: 0, + DOWNLOAD: 1, +}; + const ErrCode = { INVALID_ARGS: 13900020, RESULT_ERROR: 13900042, @@ -343,12 +349,33 @@ function parseDocumentPickerSaveOption(args, action) { if ((option.fileSuffixChoices !== undefined) && option.fileSuffixChoices.length > 0) { config.parameters.key_file_suffix_choices = option.fileSuffixChoices; } + if (option.pickerMode !== undefined) { + config.parameters.mode = option.pickerMode; // todo: 确定对方接收pickerMode的参数名 + } } console.log('[picker] document save config: ' + JSON.stringify(config)); return config; } +function getDownloadPickerResult(args) { + let saveResult = { + error: undefined, + data: undefined + }; + if (args.want && args.want.parameters) { + console.log('lby : args.want.parameters begin'); + if (args.want.parameters.pick_path_return) { + console.log('lby : pick_path_return begin'); + saveResult.data = args.want.parameters.pick_path_return; + } else { + saveResult.data = args.want.parameters['ability.params.stream']; + } + } + console.log('[picker] download saveResult: ' + JSON.stringify(saveResult)); + return saveResult; +} + function getDocumentPickerSaveResult(args) { let saveResult = { error: undefined, @@ -379,6 +406,23 @@ function getDocumentPickerSaveResult(args) { return saveResult; } +function startDownloadPicker(context, config) { + if (context === undefined) { + console.log('startDownloadPicker context undefined'); + throw Error('startDownloadPicker context undefined'); + } + if (config === undefined) { + console.log('startDownloadPicker config undefined'); + throw Error('startDownloadPicker config undefined'); + } + gContext = context; + let helper = pickerHelper.startDownloadPicker(gContext, config); + if (helper !== undefined) { + console.log('startDownloadPicker helper undefined'); + } + return helper; +} + async function documentPickerSave(...args) { let checkDocumentSaveArgsResult = checkArguments(args); if (checkDocumentSaveArgsResult !== undefined) { @@ -396,6 +440,30 @@ async function documentPickerSave(...args) { console.error('[picker] getContext error: ' + getContextError); throw getErr(ErrCode.CONTEXT_NO_EXIST); } + + // 判断是否为download场景 + documentSaveConfig = parseDocumentPickerSaveOption(args, ACTION.SAVE_ACTION_MODAL); + // todo: 确定对方接收ACTION的参数名 + if (documentSaveConfig.parameters.mode == DocumentSaveMode.DOWNLOAD) { + // todo: 确定对方接收pickerMode的参数名 + // todo: 确定download逻辑类名 + documentSaveResult = await startDownloadPicker(documentSaveContext, documentSaveConfig); + const saveResult = getDocumentPickerSaveResult(documentSaveResult); + if (args.length === ARGS_TWO && typeof args[ARGS_ONE] === 'function') { + return args[ARGS_ONE](saveResult.error, saveResult.data); + } else if (args.length === ARGS_ONE && typeof args[ARGS_ZERO] === 'function') { + return args[ARGS_ZERO](saveResult.error, saveResult.data); + } + return new Promise((resolve, reject) => { + if (saveResult.data !== undefined) { + resolve(saveResult.data); + } else { + reject(saveResult.error); + } + }) + } + // 否则保持原逻辑 + try { if (documentSaveContext === undefined) { throw getErr(ErrCode.CONTEXT_NO_EXIST); @@ -530,6 +598,7 @@ export default { PhotoSelectResult : PhotoSelectResult, PhotoSaveOptions : PhotoSaveOptions, DocumentSelectMode : DocumentSelectMode, + DocumentSaveMode : DocumentSaveMode, DocumentSelectOptions : DocumentSelectOptions, DocumentSaveOptions : DocumentSaveOptions, AudioSelectOptions : AudioSelectOptions, diff --git a/interfaces/kits/picker/src/modal_ui_callback.cpp b/interfaces/kits/picker/src/modal_ui_callback.cpp new file mode 100644 index 00000000..6dc741c1 --- /dev/null +++ b/interfaces/kits/picker/src/modal_ui_callback.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2023 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 "modal_ui_callback.h" +#include "picker_n_exporter.h" + +namespace OHOS { +namespace Picker { +using namespace OHOS::Ace; +using namespace std; +ModalUICallback::ModalUICallback(Ace::UIContent* uiContent, PickerCallBack* pickerCallBack) +{ + this->uiContent = uiContent; + this->pickerCallBack_ = pickerCallBack; +} + +void ModalUICallback::SetSessionId(int32_t sessionId) +{ + this->sessionId_=sessionId; +} + +void ModalUICallback::OnRelease(int32_t releaseCode) +{ + HILOG_INFO("OnRelease enter. release code is %{public}d", releaseCode); + this->uiContent->CloseModalUIExtension(this->sessionId_); + pickerCallBack_->ready = true; +} + +void ModalUICallback::OnError(int32_t code, const std::string& name, const std::string& message) +{ + HILOG_ERROR("OnError enter. errorCode=%{public}d, name=%{public}s, message=%{public}s", + code, name.c_str(), message.c_str()); +} + +void ModalUICallback::OnResultForModal(int32_t resultCode, const OHOS::AAFwk::Want &result) +{ + HILOG_INFO("OnResultForModal enter. resultCode is %{public}d", resultCode); + pickerCallBack_->uris = result.GetStringArrayParam("select-item-list"); + pickerCallBack_->isOrigin = result.GetBoolParam("isOriginal", false); + pickerCallBack_->resultCode = resultCode; + pickerCallBack_->ready = true; +} + +void ModalUICallback::OnReceive(const OHOS::AAFwk::WantParams &request) +{ + HILOG_INFO("OnReceive enter."); +} + +void ModalUICallback::OnDestroy() +{ + HILOG_INFO("OnDestroy enter."); +} +} // namespace Picker +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/picker/src/napi_error.cpp b/interfaces/kits/picker/src/napi_error.cpp new file mode 100644 index 00000000..bb797e90 --- /dev/null +++ b/interfaces/kits/picker/src/napi_error.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "napi_error.h" + +using namespace std; + +namespace OHOS { +namespace Picker { +void NapiError::SetApiName(const std::string &Name) +{ + apiName = Name; +} + +void NapiError::SaveError(int32_t ret) +{ + if (ret < 0) { + error = PickerNapiUtils::TransErrorCode(apiName, ret); + } +} + +void NapiError::HandleError(napi_env env, napi_value &errorObj) +{ + // deal with context->error + PickerNapiUtils::HandleError(env, error, errorObj, apiName); +} + +void NapiError::ThrowError(napi_env env, int32_t err, const std::string &errMsg) +{ + string message = errMsg; + if (message.empty()) { + message = "operation not support"; + if (jsErrMap.count(err) > 0) { + message = jsErrMap.at(err); + } + } + + HILOG_ERROR("ThrowError errCode:%{public}d errMsg:%{public}s", err, message.c_str()); + NAPI_CALL_RETURN_VOID(env, napi_throw_error(env, to_string(err).c_str(), message.c_str())); +} + +void NapiError::ThrowError(napi_env env, int32_t err, const char *funcName, int32_t line, const std::string &errMsg) +{ + string message = errMsg; + if (message.empty()) { + message = "operation not support"; + if (jsErrMap.count(err) > 0) { + message = jsErrMap.at(err); + } + } + + HILOG_ERROR("{%{public}s:%d} ThrowError errCode:%{public}d errMsg:%{public}s", funcName, line, + err, message.c_str()); + NAPI_CALL_RETURN_VOID(env, napi_throw_error(env, to_string(err).c_str(), message.c_str())); +} + +} // namespace Picker +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/picker/src/picker_n_exporter.cpp b/interfaces/kits/picker/src/picker_n_exporter.cpp new file mode 100644 index 00000000..77ef4bee --- /dev/null +++ b/interfaces/kits/picker/src/picker_n_exporter.cpp @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2023 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. + */ +#define ABILITY_WANT_PARAMS_UIEXTENSIONTARGETTYPE "ability.want.params.uiExtensionTargetType" +#include "picker_n_exporter.h" +#include "modal_ui_callback.h" +#include "modal_ui_extension_config.h" +#include "ability_context.h" +#include "context.h" +#include "ability.h" +#ifdef HAS_ACE_ENGINE_PART +#include "ui_content.h" +#endif +#include "ui_extension_context.h" +#include "want.h" + +namespace OHOS { +namespace Picker { +using namespace std; +using namespace FileManagement; +using namespace FileManagement::LibN; +using namespace AppExecFwk; +static std::mutex recentPathMutex; + +// 宏定义 done +// unit done +// callback done + +// 错误码 417闭环 +// 与被拉起方对齐规格 发什么、收什么 ---417找dongzheng对齐 417闭环 -- 发type、收uri +// 确认createUIExtension是否能满足要求---待dujingcheng答复 417闭环 --可以 +// 与JS互通 + +bool PickerNExporter::Export() +{ + return exports_.AddProp({ + NVal::DeclareNapiFunction("startDownloadPicker", StartDownloadPicker) + }); +} + +string PickerNExporter::GetClassName() +{ + return PickerNExporter::className_; +} + +static void StartDownloadPickerExecute(napi_env env, void *data) +{ + HILOG_INFO("lby StartDownloadPickerExecute begin"); + auto *context = static_cast(data); + while (!context->pickerCallBack->ready) { + HILOG_INFO("lby StartDownloadPickerExecute not ready."); + // std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME)); + } +} + +static void StartDownloadPickerAsyncCallbackComplete(napi_env env, napi_status status, void *data) +{ + // 返回值处理,对齐返回值后修改 + + auto *context = static_cast(data); + CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null"); + + auto jsContext = make_unique(); + jsContext->status = false; + + CHECK_ARGS_RET_VOID(env, napi_get_undefined(env, &jsContext->data), JS_ERR_PARAMETER_INVALID); + CHECK_ARGS_RET_VOID(env, napi_get_undefined(env, &jsContext->error), JS_ERR_PARAMETER_INVALID); + + const string uri = context->pickerCallBack->uri; + napi_value jsUri = nullptr; + CHECK_ARGS_RET_VOID(env, napi_create_string_utf8(env, uri.c_str(), + NAPI_AUTO_LENGTH, &jsUri), JS_INNER_FAIL); + if (jsUri == nullptr) { + HILOG_ERROR("jsUri is nullptr."); + break; + } + status = napi_set_named_property(env, result, "uri", jsUri); + if (status != napi_ok) { + HILOG_ERROR("napi_set_named_property uri failed"); + } + if (result != nullptr) { + jsContext->data = result; + jsContext->status = true; + } else { + PickerNapiUtils::CreateNapiErrorObject(env, jsContext->error, ERR_MEM_ALLOCATION, + "failed to create js object"); + } + if (context->work != nullptr) { + PickerNapiUtils::InvokeJSAsyncMethod(env, context->deferred, context->callbackRef, + context->work, *jsContext); + } + delete context; +} + +Ace::UIContent *GetUIContent(napi_env env, napi_callback_info info, + unique_ptr &AsyncContext) +{ + bool isStageMode = false; + // 仅有StageContext可以转化为AbilityContext + napi_status status = AbilityRuntime::IsStageContext(env, AsyncContext->argv[ARGS_ZERO], isStageMode); + if (status != napi_ok || !isStageMode) { + HILOG_ERROR("is not StageMode context"); + return nullptr; + } + auto context = AbilityRuntime::GetStageModeContext(env, AsyncContext->argv[ARGS_ZERO]); + if (context == nullptr) { + HILOG_ERROR("Failed to get native stage context instance"); + return nullptr; + } + auto abilityContext = AbilityRuntime::Context::ConvertTo(context); + if (abilityContext == nullptr) { + auto uiExtensionContext = AbilityRuntime::Context::ConvertTo(context); + if (uiExtensionContext == nullptr) { + HILOG_ERROR("Fail to convert to abilityContext or uiExtensionContext"); + return nullptr; + } + return uiExtensionContext->GetUIContent(); + } + return abilityContext->GetUIContent(); +} + +static napi_value StartPickerExtension(napi_env env, napi_callback_info info, + unique_ptr &AsyncContext) +{ + HILOG_INFO("lby StartPickerExtension begin."); + Ace::UIContent *uiContent = GetUIContent(env, info, AsyncContext); + if (uiContent == nullptr) { + HILOG_ERROR("lby get uiContent failed"); + return nullptr; + } + AAFwk::Want request; + AppExecFwk::UnwrapWant(env, AsyncContext->argv[ARGS_ONE], request); + // todo: 这里是否要约定targetType + // 对齐todo:request的内容是要传给被拉起方的,需要对齐 + // request、AsyncContext + std::string targetType = "filedownload"; + request.SetParam(ABILITY_WANT_PARAMS_UIEXTENSIONTARGETTYPE, targetType); + AsyncContext->pickerCallBack = make_shared(); + auto callback = std::make_shared(uiContent, AsyncContext->pickerCallBack.get()); + // todo: 这里要实现 ModalUICallback + Ace::ModalUIExtensionCallbacks extensionCallback = { + std::bind(&ModalUICallback::OnRelease, callback, std::placeholders::_1), + std::bind(&ModalUICallback::OnResultForModal, callback, std::placeholders::_1, std::placeholders::_2), + std::bind(&ModalUICallback::OnReceive, callback, std::placeholders::_1), + std::bind(&ModalUICallback::OnError, callback, std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3), + std::bind(&ModalUICallback::OnDestroy, callback), + }; + Ace::ModalUIExtensionConfig config; + config.isProhibitBack = true; + int sessionId = uiContent->CreateModalUIExtension(request, extensionCallback, config); + if (sessionId == 0) { + HILOG_ERROR("lby create modalUIExtension failed"); + return nullptr; + } + callback->SetSessionId(sessionId); + napi_value result = nullptr; + // todo:这里JS_INNER_FAIL未定义 + CHECK_ARGS(env, napi_get_boolean(env, true, &result), JS_INNER_FAIL); + return result; +} + +// todo:模板理解+拆解 +template +static napi_status AsyncContextSetStaticObjectInfo(napi_env env, napi_callback_info info, + AsyncContext &asyncContext, const size_t minArgs, const size_t maxArgs) +{ + HILOG_INFO("lby AsyncContextSetStaticObjectInfo begin."); + // 设置上下文静态信息 + napi_value thisVar = nullptr; + asyncContext->argc = maxArgs; + CHECK_STATUS_RET(napi_get_cb_info(env, info, &asyncContext->argc, &(asyncContext->argv[ARGS_ZERO]), &thisVar, + nullptr), "Failed to get cb info"); + CHECK_COND_RET(((asyncContext->argc >= minArgs) && (asyncContext->argc <= maxArgs)), napi_invalid_arg, + "Number of args is invalid"); + if (minArgs > 0) { + CHECK_COND_RET(asyncContext->argv[ARGS_ZERO] != nullptr, napi_invalid_arg, "Argument list is empty"); + } + // 获取context->callbackRef + CHECK_STATUS_RET(PickerNapiUtils::GetParamCallback(env, asyncContext), "Failed to get callback param!"); + return napi_ok; +} + +static napi_value ParseArgsStartDownloadPicker(napi_env env, napi_callback_info info, + unique_ptr &context) +{ + // 开始解析参数 + HILOG_INFO("lby ParseArgsStartDownloadPicker begin."); + constexpr size_t minArgs = ARGS_TWO; + constexpr size_t maxArgs = ARGS_THREE; + CHECK_ARGS(env, AsyncContextSetStaticObjectInfo(env, info, context, minArgs, maxArgs), + JS_ERR_PARAMETER_INVALID); + // todo:实现PickerNapiUtils::GetParamCallback + // todo: 这里为什么要设置两次GetParamCallback + NAPI_CALL(env, PickerNapiUtils::GetParamCallback(env, context)); + CHECK_NULLPTR_RET(StartPickerExtension(env, info, context)); + napi_value result = nullptr; + CHECK_ARGS(env, napi_get_boolean(env, true, &result), JS_INNER_FAIL); + return result; +} + +napi_value PickerNExporter::StartDownloadPicker(napi_env env, napi_callback_info info) +{ + // todo:PickerAsyncContext 理解+拆解 + HILOG_INFO("lby StartDownloadPicker begin."); + unique_ptr asyncContext = make_unique(); + // asyncContext->resultNapiType = ResultNapiType::TYPE_PHOTOACCESS_HELPER; + // todo: 这里ParseArgsStartDownloadPicker完后已经拉起了UI,NapiCreateAsyncWork的作用 + ParseArgsStartDownloadPicker(env, info, asyncContext); + // todo:实现PickerNapiUtils::NapiCreateAsyncWork + return PickerNapiUtils::NapiCreateAsyncWork(env, asyncContext, "StrartDownloadPicker", + StartDownloadPickerExecute, StartDownloadPickerAsyncCallbackComplete); +} + +PickerNExporter::PickerNExporter(napi_env env, napi_value exports) : NExporter(env, exports) +{ + HILOG_INFO("PickerNExporter is called."); +} + +PickerNExporter::~PickerNExporter() {} +} // namespace Picker +} // namespace OHOS diff --git a/interfaces/kits/picker/src/picker_napi_utils.cpp b/interfaces/kits/picker/src/picker_napi_utils.cpp new file mode 100644 index 00000000..2a28a7ff --- /dev/null +++ b/interfaces/kits/picker/src/picker_napi_utils.cpp @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#define MLOG_TAG "PickerNapiUtils" + +#include "picker_napi_utils.h" +#include "ipc_skeleton.h" +#include "picker_n_exporter.h" + +using namespace std; + +namespace OHOS { +namespace Picker { +static const string EMPTY_STRING = ""; + +void PickerNapiUtils::CreateNapiErrorObject(napi_env env, napi_value &errorObj, const int32_t errCode, + const string errMsg) +{ + napi_status statusError; + napi_value napiErrorCode = nullptr; + napi_value napiErrorMsg = nullptr; + statusError = napi_create_string_utf8(env, to_string(errCode).c_str(), NAPI_AUTO_LENGTH, &napiErrorCode); + if (statusError == napi_ok) { + statusError = napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &napiErrorMsg); + if (statusError == napi_ok) { + statusError = napi_create_error(env, napiErrorCode, napiErrorMsg, &errorObj); + if (statusError == napi_ok) { + HILOG_DEBUG("napi_create_error success"); + } + } + } +} + +void PickerNapiUtils::HandleError(napi_env env, int error, napi_value &errorObj, const string &Name) +{ + if (error == ERR_DEFAULT) { + return; + } + + string errMsg = "System inner fail"; + int originalError = error; + if (jsErrMap.count(error) > 0) { + errMsg = jsErrMap.at(error); + } else { + error = JS_INNER_FAIL; + } + CreateNapiErrorObject(env, errorObj, error, errMsg); + errMsg = Name + " " + errMsg; + HILOG_ERROR("Error: %{public}s, js errcode:%{public}d ", errMsg.c_str(), originalError); +} + +napi_status PickerNapiUtils::GetParamFunction(napi_env env, napi_value arg, napi_ref &callbackRef) +{ + napi_valuetype valueType = napi_undefined; + CHECK_STATUS_RET(napi_typeof(env, arg, &valueType), "Failed to get type"); + CHECK_COND_RET(valueType == napi_function, napi_function_expected, "Type is not as expected function"); + CHECK_STATUS_RET(napi_create_reference(env, arg, NAPI_INIT_REF_COUNT, &callbackRef), "Failed to make callbackref"); + return napi_ok; +} + +napi_status PickerNapiUtils::HasCallback(napi_env env, const size_t argc, const napi_value argv[], + bool &isCallback) +{ + isCallback = false; + if (argc < ARGS_ONE) { + return napi_ok; + } + napi_valuetype valueType = napi_undefined; + CHECK_STATUS_RET(napi_typeof(env, argv[argc - 1], &valueType), "Failed to get type"); + isCallback = (valueType == napi_function); + return napi_ok; +} + +template +napi_status PickerNapiUtils::GetParamCallback(napi_env env, AsyncContext &context) +{ + /* Parse the last argument into callbackref if any */ + bool isCallback = false; + CHECK_STATUS_RET(HasCallback(env, context->argc, context->argv, isCallback), "Failed to check callback"); + if (isCallback) { + CHECK_STATUS_RET(GetParamFunction(env, context->argv[context->argc - 1], context->callbackRef), + "Failed to get callback"); + } + return napi_ok; +} + +void PickerNapiUtils::InvokeJSAsyncMethod(napi_env env, napi_deferred deferred, napi_ref callbackRef, + napi_async_work work, const JSAsyncContextOutput &asyncContext) +{ + napi_value retVal; + napi_value callback = nullptr; + + /* Deferred is used when JS Callback method expects a promise value */ + if (deferred) { + if (asyncContext.status) { + napi_resolve_deferred(env, deferred, asyncContext.data); + } else { + napi_reject_deferred(env, deferred, asyncContext.error); + } + } else { + napi_value result[ARGS_TWO]; + result[PARAM0] = asyncContext.error; + result[PARAM1] = asyncContext.data; + napi_get_reference_value(env, callbackRef, &callback); + napi_call_function(env, nullptr, callback, ARGS_TWO, result, &retVal); + napi_delete_reference(env, callbackRef); + } + napi_delete_async_work(env, work); +} + +template +napi_value PickerNapiUtils::NapiCreateAsyncWork(napi_env env, unique_ptr &asyncContext, + const string &resourceName, void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *)) +{ + napi_value result = nullptr; + napi_value resource = nullptr; + NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result); + NAPI_CREATE_RESOURCE_NAME(env, resource, resourceName.c_str(), asyncContext); + + NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, execute, complete, + static_cast(asyncContext.get()), &asyncContext->work)); + NAPI_CALL(env, napi_queue_async_work(env, asyncContext->work)); + asyncContext.release(); + + return result; +} + +int PickerNapiUtils::TransErrorCode(const string &Name, int error) +{ + HILOG_ERROR("interface: %{public}s, server errcode:%{public}d ", Name.c_str(), error); + // Transfer Server error to napi error code + // if (error <= E_COMMON_START && error >= E_COMMON_END) { + // error = JS_INNER_FAIL; + // } else if (trans2JsError.count(error)) { + // error = trans2JsError.at(error); + // } + return error; +} + +template napi_status PickerNapiUtils::GetParamCallback>(napi_env env, + unique_ptr &context); + +template napi_value PickerNapiUtils::NapiCreateAsyncWork(napi_env env, + unique_ptr &asyncContext, const string &resourceName, + void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *)); +} // namespace Picker +} // namespace OHOS -- Gitee From 6bedb534052611431e3a2c0101dc63537e7783df Mon Sep 17 00:00:00 2001 From: libuyan Date: Fri, 19 Apr 2024 17:57:39 +0800 Subject: [PATCH 02/13] add target Signed-off-by: libuyan --- interfaces/kits/picker/src/modal_ui_callback.cpp | 2 +- interfaces/kits/picker/src/picker_n_exporter.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/interfaces/kits/picker/src/modal_ui_callback.cpp b/interfaces/kits/picker/src/modal_ui_callback.cpp index 6dc741c1..c25e67e3 100644 --- a/interfaces/kits/picker/src/modal_ui_callback.cpp +++ b/interfaces/kits/picker/src/modal_ui_callback.cpp @@ -47,7 +47,7 @@ void ModalUICallback::OnError(int32_t code, const std::string& name, const std:: void ModalUICallback::OnResultForModal(int32_t resultCode, const OHOS::AAFwk::Want &result) { HILOG_INFO("OnResultForModal enter. resultCode is %{public}d", resultCode); - pickerCallBack_->uris = result.GetStringArrayParam("select-item-list"); + pickerCallBack_->uri = result.GetStringParam("select-item-list"); pickerCallBack_->isOrigin = result.GetBoolParam("isOriginal", false); pickerCallBack_->resultCode = resultCode; pickerCallBack_->ready = true; diff --git a/interfaces/kits/picker/src/picker_n_exporter.cpp b/interfaces/kits/picker/src/picker_n_exporter.cpp index 77ef4bee..406a1967 100644 --- a/interfaces/kits/picker/src/picker_n_exporter.cpp +++ b/interfaces/kits/picker/src/picker_n_exporter.cpp @@ -83,8 +83,8 @@ static void StartDownloadPickerAsyncCallbackComplete(napi_env env, napi_status s NAPI_AUTO_LENGTH, &jsUri), JS_INNER_FAIL); if (jsUri == nullptr) { HILOG_ERROR("jsUri is nullptr."); - break; } + napi_value result = nullptr; status = napi_set_named_property(env, result, "uri", jsUri); if (status != napi_ok) { HILOG_ERROR("napi_set_named_property uri failed"); -- Gitee From 9f78f3d6eec6b7bf10c2da0218a9f41280887cbe Mon Sep 17 00:00:00 2001 From: libuyan Date: Wed, 24 Apr 2024 22:48:17 +0800 Subject: [PATCH 03/13] add target Signed-off-by: libuyan --- interfaces/kits/picker/include/napi_error.h | 1 - .../kits/picker/include/picker_n_exporter.h | 8 +- .../kits/picker/include/picker_napi_utils.h | 15 --- interfaces/kits/picker/picker.js | 98 +++++++++++-------- .../kits/picker/src/modal_ui_callback.cpp | 16 +-- interfaces/kits/picker/src/napi_error.cpp | 7 -- .../kits/picker/src/picker_n_exporter.cpp | 92 +++++++---------- .../kits/picker/src/picker_napi_utils.cpp | 50 ---------- 8 files changed, 106 insertions(+), 181 deletions(-) diff --git a/interfaces/kits/picker/include/napi_error.h b/interfaces/kits/picker/include/napi_error.h index e267d562..31fe1845 100644 --- a/interfaces/kits/picker/include/napi_error.h +++ b/interfaces/kits/picker/include/napi_error.h @@ -28,7 +28,6 @@ struct NapiError { int32_t error = 0; std::string apiName; void SetApiName(const std::string &Name); - void SaveError(int32_t ret); void HandleError(napi_env env, napi_value &errorObj); EXPORT static void ThrowError(napi_env env, int32_t err, const std::string &errMsg = ""); EXPORT static void ThrowError(napi_env env, int32_t err, const char *func, int32_t line, diff --git a/interfaces/kits/picker/include/picker_n_exporter.h b/interfaces/kits/picker/include/picker_n_exporter.h index dc821db9..9f56bb87 100644 --- a/interfaces/kits/picker/include/picker_n_exporter.h +++ b/interfaces/kits/picker/include/picker_n_exporter.h @@ -16,6 +16,7 @@ #define INTERFACES_KITS_NATIVE_PICKER_N_EXPOTER_H #include +#include #include "data_ability_helper.h" #include "data_ability_observer_stub.h" #include "data_ability_predicates.h" @@ -37,7 +38,6 @@ struct NameListArg { int direntNum = 0; }; -// 对齐todo: 返回值的内容需要對齊 struct PickerCallBack { bool ready = false; bool isOrigin; @@ -45,7 +45,6 @@ struct PickerCallBack { string uri; }; -// 对齐todo:定制上下文内容 struct PickerAsyncContext : public NapiError { napi_async_work work; napi_deferred deferred; @@ -58,7 +57,7 @@ struct PickerAsyncContext : public NapiError { class PickerNExporter final : public FileManagement::LibN::NExporter { public: inline static const std::string className_ = "Picker"; - static napi_value StartDownloadPicker(napi_env env, napi_callback_info info); + static napi_value StartModalPicker(napi_env env, napi_callback_info info); bool Export() override; std::string GetClassName() override; PickerNExporter(napi_env env, napi_value exports); @@ -67,9 +66,6 @@ public: // const std::string RECENT_PATH = "/storage/Users/.Recent/"; const std::string FILE_ACCESS_PERMISSION = "ohos.permission.FILE_ACCESS_MANAGER"; -constexpr int BUF_SIZE = 1024; -constexpr int MAX_RECENT_SIZE = 100; -static thread_local napi_ref sConstructor_; } // namespace FileAccessFwk } // namespace OHOS #endif // INTERFACES_KITS_NATIVE_PICKER_N_EXPOTER_H diff --git a/interfaces/kits/picker/include/picker_napi_utils.h b/interfaces/kits/picker/include/picker_napi_utils.h index ccdd5c94..6961a80d 100644 --- a/interfaces/kits/picker/include/picker_napi_utils.h +++ b/interfaces/kits/picker/include/picker_napi_utils.h @@ -199,15 +199,6 @@ const int32_t ERR_DEFAULT = 0; const int32_t ERR_MEM_ALLOCATION = 2; const int32_t ERR_INVALID_OUTPUT = 3; -const int32_t TRASH_SMART_ALBUM_ID = 1; -const std::string TRASH_SMART_ALBUM_NAME = "TrashAlbum"; -const int32_t FAVORIT_SMART_ALBUM_ID = 2; -const std::string FAVORIT_SMART_ALBUM_NAME = "FavoritAlbum"; - -const std::string API_VERSION = "api_version"; - -const std::string PENDING_STATUS = "pending"; - struct JSAsyncContextOutput { napi_value error; napi_value data; @@ -224,15 +215,9 @@ struct NapiClassInfo { /* Util class used by napi asynchronous methods for making call to js callback function */ class PickerNapiUtils { public: - static int TransErrorCode(const std::string &Name, int error); static void HandleError(napi_env env, int error, napi_value &errorObj, const std::string &Name); static void CreateNapiErrorObject(napi_env env, napi_value &errorObj, const int32_t errCode, const std::string errMsg); - template - static napi_status GetParamCallback(napi_env env, AsyncContext &context); - static napi_status HasCallback(napi_env env, const size_t argc, const napi_value argv[], - bool &isCallback); - static napi_status GetParamFunction(napi_env env, napi_value arg, napi_ref &callbackRef); static void InvokeJSAsyncMethod(napi_env env, napi_deferred deferred, napi_ref callbackRef, napi_async_work work, const JSAsyncContextOutput &asyncContext); template diff --git a/interfaces/kits/picker/picker.js b/interfaces/kits/picker/picker.js index b88f48ce..6ca0e2ee 100644 --- a/interfaces/kits/picker/picker.js +++ b/interfaces/kits/picker/picker.js @@ -14,6 +14,8 @@ */ const pickerHelper = requireInternal('file.picker'); +let gContext = undefined; + const PhotoViewMIMETypes = { IMAGE_TYPE: 'image/*', VIDEO_TYPE: 'video/*', @@ -32,6 +34,14 @@ const DocumentSaveMode = { DOWNLOAD: 1, }; +const ExtTypes = { + DOWNLOAD_TYPE: 'download', +}; + +const PickerDetailType = { + FILE_MGR_AUTH: 'downloadAuth', +}; + const ErrCode = { INVALID_ARGS: 13900020, RESULT_ERROR: 13900042, @@ -57,6 +67,7 @@ const ACTION = { SELECT_ACTION_MODAL: 'ohos.want.action.OPEN_FILE_SERVICE', SAVE_ACTION: 'ohos.want.action.CREATE_FILE', SAVE_ACTION_MODAL: 'ohos.want.action.CREATE_FILE_SERVICE', + SAVE_ACTION_DOWNLOAD: 'ohos.want.action.DOWNLOAD', } const CREATE_FILE_NAME_LENGTH_LIMIT = 256; @@ -333,6 +344,7 @@ function parseDocumentPickerSaveOption(args, action) { action: action, parameters: { startMode: 'save', + pickerMode: DocumentSaveMode.DEFAULT, } }; @@ -349,8 +361,11 @@ function parseDocumentPickerSaveOption(args, action) { if ((option.fileSuffixChoices !== undefined) && option.fileSuffixChoices.length > 0) { config.parameters.key_file_suffix_choices = option.fileSuffixChoices; } - if (option.pickerMode !== undefined) { - config.parameters.mode = option.pickerMode; // todo: 确定对方接收pickerMode的参数名 + if (option.pickerMode === DocumentSaveMode.DOWNLOAD) { + config.parameters.pickerMode = option.pickerMode; + config.action = ACTION.SAVE_ACTION_DOWNLOAD; + config.parameters.extType = ExtTypes.DOWNLOAD_TYPE; + config.parameters.pickerType = PickerDetailType.FILE_MGR_AUTH; } } @@ -358,21 +373,15 @@ function parseDocumentPickerSaveOption(args, action) { return config; } -function getDownloadPickerResult(args) { +function getModalPickerResult(args) { let saveResult = { error: undefined, data: undefined - }; - if (args.want && args.want.parameters) { - console.log('lby : args.want.parameters begin'); - if (args.want.parameters.pick_path_return) { - console.log('lby : pick_path_return begin'); - saveResult.data = args.want.parameters.pick_path_return; - } else { - saveResult.data = args.want.parameters['ability.params.stream']; - } } - console.log('[picker] download saveResult: ' + JSON.stringify(saveResult)); + if (args) { + saveResult.data = args.uri; + } + console.log('modal picker: download saveResult: ' + JSON.stringify(saveResult)); return saveResult; } @@ -406,23 +415,44 @@ function getDocumentPickerSaveResult(args) { return saveResult; } -function startDownloadPicker(context, config) { +function startModalPicker(context, config) { if (context === undefined) { - console.log('startDownloadPicker context undefined'); - throw Error('startDownloadPicker context undefined'); + console.log('modal picker: startModalPicker context undefined.'); + throw Error('modal picker: startModalPicker context undefined.'); } if (config === undefined) { - console.log('startDownloadPicker config undefined'); - throw Error('startDownloadPicker config undefined'); + console.log('modal picker: startModalPicker config undefined.'); + throw Error('modal picker: startModalPicker config undefined.'); } gContext = context; - let helper = pickerHelper.startDownloadPicker(gContext, config); + if (pickerHelper === undefined) { + console.log('modal picker: pickerHelper undefined.') + } + let helper = pickerHelper.startModalPicker(gContext, config); if (helper !== undefined) { - console.log('startDownloadPicker helper undefined'); + console.log('modal picker: startModalPicker helper undefined.'); } return helper; } +async function modalPicker(args, context, config) { + console.log('modal picker: config: ' + JSON.stringify(config)); + let modalSaveResult = await startModalPicker(context, config); + const saveResult = getModalPickerResult(modalSaveResult); + if (args.length === ARGS_TWO && typeof args[ARGS_ONE] === 'function') { + return args[ARGS_ONE](saveResult.error, saveResult.data); + } else if (args.length === ARGS_ONE && typeof args[ARGS_ZERO] === 'function') { + return args[ARGS_ZERO](saveResult.error, saveResult.data); + } + return new Promise((resolve, reject) => { + if (saveResult.data !== undefined) { + resolve(saveResult.data); + } else { + reject(saveResult.error); + } + }) +} + async function documentPickerSave(...args) { let checkDocumentSaveArgsResult = checkArguments(args); if (checkDocumentSaveArgsResult !== undefined) { @@ -441,28 +471,12 @@ async function documentPickerSave(...args) { throw getErr(ErrCode.CONTEXT_NO_EXIST); } - // 判断是否为download场景 documentSaveConfig = parseDocumentPickerSaveOption(args, ACTION.SAVE_ACTION_MODAL); - // todo: 确定对方接收ACTION的参数名 - if (documentSaveConfig.parameters.mode == DocumentSaveMode.DOWNLOAD) { - // todo: 确定对方接收pickerMode的参数名 - // todo: 确定download逻辑类名 - documentSaveResult = await startDownloadPicker(documentSaveContext, documentSaveConfig); - const saveResult = getDocumentPickerSaveResult(documentSaveResult); - if (args.length === ARGS_TWO && typeof args[ARGS_ONE] === 'function') { - return args[ARGS_ONE](saveResult.error, saveResult.data); - } else if (args.length === ARGS_ONE && typeof args[ARGS_ZERO] === 'function') { - return args[ARGS_ZERO](saveResult.error, saveResult.data); - } - return new Promise((resolve, reject) => { - if (saveResult.data !== undefined) { - resolve(saveResult.data); - } else { - reject(saveResult.error); - } - }) + if (documentSaveConfig.parameters.pickerMode === DocumentSaveMode.DOWNLOAD) { + console.log('modal picker: will start modal picker process. (DOWNLOAD)'); + modalPicker(args, documentSaveContext, documentSaveConfig); + return; } - // 否则保持原逻辑 try { if (documentSaveContext === undefined) { @@ -569,6 +583,7 @@ function DocumentSaveOptions() { this.newFileNames = undefined; this.defaultFilePathUri = undefined; this.fileSuffixChoices = undefined; + this.pickerMode = DocumentSaveMode.DEFAULT; } function AudioSelectOptions() {} @@ -593,6 +608,9 @@ function AudioViewPicker() { } export default { + startModalPicker, + ExtTypes : ExtTypes, + PickerDetailType: PickerDetailType, PhotoViewMIMETypes : PhotoViewMIMETypes, PhotoSelectOptions : PhotoSelectOptions, PhotoSelectResult : PhotoSelectResult, diff --git a/interfaces/kits/picker/src/modal_ui_callback.cpp b/interfaces/kits/picker/src/modal_ui_callback.cpp index c25e67e3..7ac2b9c6 100644 --- a/interfaces/kits/picker/src/modal_ui_callback.cpp +++ b/interfaces/kits/picker/src/modal_ui_callback.cpp @@ -33,34 +33,36 @@ void ModalUICallback::SetSessionId(int32_t sessionId) void ModalUICallback::OnRelease(int32_t releaseCode) { - HILOG_INFO("OnRelease enter. release code is %{public}d", releaseCode); + HILOG_INFO("modal picker: OnRelease enter. release code is %{public}d", releaseCode); this->uiContent->CloseModalUIExtension(this->sessionId_); pickerCallBack_->ready = true; } void ModalUICallback::OnError(int32_t code, const std::string& name, const std::string& message) { - HILOG_ERROR("OnError enter. errorCode=%{public}d, name=%{public}s, message=%{public}s", + HILOG_ERROR("modal picker: OnError enter. errorCode=%{public}d, name=%{public}s, message=%{public}s", code, name.c_str(), message.c_str()); } void ModalUICallback::OnResultForModal(int32_t resultCode, const OHOS::AAFwk::Want &result) { - HILOG_INFO("OnResultForModal enter. resultCode is %{public}d", resultCode); - pickerCallBack_->uri = result.GetStringParam("select-item-list"); - pickerCallBack_->isOrigin = result.GetBoolParam("isOriginal", false); + HILOG_INFO("modal picker: OnResultForModal enter. resultCode is %{public}d", resultCode); + if (result.GetParams().HasParam("downloadNewUri")) { + HILOG_INFO("modal picker: downloadNewUri exit."); + pickerCallBack_->uri = result.GetStringParam("downloadNewUri"); + } pickerCallBack_->resultCode = resultCode; pickerCallBack_->ready = true; } void ModalUICallback::OnReceive(const OHOS::AAFwk::WantParams &request) { - HILOG_INFO("OnReceive enter."); + HILOG_INFO("modal picker: OnReceive enter."); } void ModalUICallback::OnDestroy() { - HILOG_INFO("OnDestroy enter."); + HILOG_INFO("modal picker: OnDestroy enter."); } } // namespace Picker } // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/picker/src/napi_error.cpp b/interfaces/kits/picker/src/napi_error.cpp index bb797e90..000e1168 100644 --- a/interfaces/kits/picker/src/napi_error.cpp +++ b/interfaces/kits/picker/src/napi_error.cpp @@ -24,13 +24,6 @@ void NapiError::SetApiName(const std::string &Name) apiName = Name; } -void NapiError::SaveError(int32_t ret) -{ - if (ret < 0) { - error = PickerNapiUtils::TransErrorCode(apiName, ret); - } -} - void NapiError::HandleError(napi_env env, napi_value &errorObj) { // deal with context->error diff --git a/interfaces/kits/picker/src/picker_n_exporter.cpp b/interfaces/kits/picker/src/picker_n_exporter.cpp index 406a1967..6b18ed65 100644 --- a/interfaces/kits/picker/src/picker_n_exporter.cpp +++ b/interfaces/kits/picker/src/picker_n_exporter.cpp @@ -31,21 +31,12 @@ using namespace std; using namespace FileManagement; using namespace FileManagement::LibN; using namespace AppExecFwk; -static std::mutex recentPathMutex; - -// 宏定义 done -// unit done -// callback done - -// 错误码 417闭环 -// 与被拉起方对齐规格 发什么、收什么 ---417找dongzheng对齐 417闭环 -- 发type、收uri -// 确认createUIExtension是否能满足要求---待dujingcheng答复 417闭环 --可以 -// 与JS互通 +#define WAIT_TIME_MS 100 bool PickerNExporter::Export() { return exports_.AddProp({ - NVal::DeclareNapiFunction("startDownloadPicker", StartDownloadPicker) + NVal::DeclareNapiFunction("startModalPicker", StartModalPicker) }); } @@ -54,20 +45,19 @@ string PickerNExporter::GetClassName() return PickerNExporter::className_; } -static void StartDownloadPickerExecute(napi_env env, void *data) +static void StartModalPickerExecute(napi_env env, void *data) { - HILOG_INFO("lby StartDownloadPickerExecute begin"); + HILOG_INFO("modal picker: StartModalPickerExecute begin"); auto *context = static_cast(data); while (!context->pickerCallBack->ready) { - HILOG_INFO("lby StartDownloadPickerExecute not ready."); - // std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME)); + std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME_MS)); } + HILOG_INFO("modal picker: StartModalPickerExecute is ready."); } -static void StartDownloadPickerAsyncCallbackComplete(napi_env env, napi_status status, void *data) +static void StartModalPickerAsyncCallbackComplete(napi_env env, napi_status status, void *data) { - // 返回值处理,对齐返回值后修改 - + HILOG_INFO("modal picker: StartModalPickerAsyncCallbackComplete begin."); auto *context = static_cast(data); CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null"); @@ -78,6 +68,7 @@ static void StartDownloadPickerAsyncCallbackComplete(napi_env env, napi_status s CHECK_ARGS_RET_VOID(env, napi_get_undefined(env, &jsContext->error), JS_ERR_PARAMETER_INVALID); const string uri = context->pickerCallBack->uri; + HILOG_DEBUG("modal picker: uri is %{public}s.", uri.c_str()); napi_value jsUri = nullptr; CHECK_ARGS_RET_VOID(env, napi_create_string_utf8(env, uri.c_str(), NAPI_AUTO_LENGTH, &jsUri), JS_INNER_FAIL); @@ -85,9 +76,10 @@ static void StartDownloadPickerAsyncCallbackComplete(napi_env env, napi_status s HILOG_ERROR("jsUri is nullptr."); } napi_value result = nullptr; + napi_create_object(env, &result); status = napi_set_named_property(env, result, "uri", jsUri); if (status != napi_ok) { - HILOG_ERROR("napi_set_named_property uri failed"); + HILOG_ERROR("modal picker: napi_set_named_property uri failed"); } if (result != nullptr) { jsContext->data = result; @@ -107,22 +99,21 @@ Ace::UIContent *GetUIContent(napi_env env, napi_callback_info info, unique_ptr &AsyncContext) { bool isStageMode = false; - // 仅有StageContext可以转化为AbilityContext napi_status status = AbilityRuntime::IsStageContext(env, AsyncContext->argv[ARGS_ZERO], isStageMode); if (status != napi_ok || !isStageMode) { - HILOG_ERROR("is not StageMode context"); + HILOG_ERROR("modal picker: is not StageMode context"); return nullptr; } auto context = AbilityRuntime::GetStageModeContext(env, AsyncContext->argv[ARGS_ZERO]); if (context == nullptr) { - HILOG_ERROR("Failed to get native stage context instance"); + HILOG_ERROR("modal picker: Failed to get native stage context instance"); return nullptr; } auto abilityContext = AbilityRuntime::Context::ConvertTo(context); if (abilityContext == nullptr) { auto uiExtensionContext = AbilityRuntime::Context::ConvertTo(context); if (uiExtensionContext == nullptr) { - HILOG_ERROR("Fail to convert to abilityContext or uiExtensionContext"); + HILOG_ERROR("modal picker: Fail to convert to abilityContext or uiExtensionContext"); return nullptr; } return uiExtensionContext->GetUIContent(); @@ -133,35 +124,36 @@ Ace::UIContent *GetUIContent(napi_env env, napi_callback_info info, static napi_value StartPickerExtension(napi_env env, napi_callback_info info, unique_ptr &AsyncContext) { - HILOG_INFO("lby StartPickerExtension begin."); + HILOG_INFO("modal picker: StartPickerExtension begin."); Ace::UIContent *uiContent = GetUIContent(env, info, AsyncContext); if (uiContent == nullptr) { - HILOG_ERROR("lby get uiContent failed"); + HILOG_ERROR("modal picker: get uiContent failed"); return nullptr; } AAFwk::Want request; AppExecFwk::UnwrapWant(env, AsyncContext->argv[ARGS_ONE], request); - // todo: 这里是否要约定targetType - // 对齐todo:request的内容是要传给被拉起方的,需要对齐 - // request、AsyncContext - std::string targetType = "filedownload"; + + std::string targetType = request.GetStringParam("extType"); + std::string pickerType; + if (request.GetParams().HasParam("pickerType")) { + pickerType = request.GetStringParam("pickerType"); + } request.SetParam(ABILITY_WANT_PARAMS_UIEXTENSIONTARGETTYPE, targetType); AsyncContext->pickerCallBack = make_shared(); auto callback = std::make_shared(uiContent, AsyncContext->pickerCallBack.get()); - // todo: 这里要实现 ModalUICallback Ace::ModalUIExtensionCallbacks extensionCallback = { - std::bind(&ModalUICallback::OnRelease, callback, std::placeholders::_1), - std::bind(&ModalUICallback::OnResultForModal, callback, std::placeholders::_1, std::placeholders::_2), - std::bind(&ModalUICallback::OnReceive, callback, std::placeholders::_1), - std::bind(&ModalUICallback::OnError, callback, std::placeholders::_1, std::placeholders::_2, + .onRelease = std::bind(&ModalUICallback::OnRelease, callback, std::placeholders::_1), + .onResult = std::bind(&ModalUICallback::OnResultForModal, callback, std::placeholders::_1, std::placeholders::_2), + .onReceive = std::bind(&ModalUICallback::OnReceive, callback, std::placeholders::_1), + .onError = std::bind(&ModalUICallback::OnError, callback, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), - std::bind(&ModalUICallback::OnDestroy, callback), + .onDestroy = std::bind(&ModalUICallback::OnDestroy, callback), }; Ace::ModalUIExtensionConfig config; - config.isProhibitBack = true; + HILOG_INFO("modal picker: will CreateModalUIExtension by extType: %{public}s, pickerType: %{public}s", targetType.c_str(), pickerType.c_str()); int sessionId = uiContent->CreateModalUIExtension(request, extensionCallback, config); if (sessionId == 0) { - HILOG_ERROR("lby create modalUIExtension failed"); + HILOG_ERROR("modal picker create modalUIExtension failed"); return nullptr; } callback->SetSessionId(sessionId); @@ -176,8 +168,7 @@ template static napi_status AsyncContextSetStaticObjectInfo(napi_env env, napi_callback_info info, AsyncContext &asyncContext, const size_t minArgs, const size_t maxArgs) { - HILOG_INFO("lby AsyncContextSetStaticObjectInfo begin."); - // 设置上下文静态信息 + HILOG_INFO("modal picker: AsyncContextSetStaticObjectInfo begin."); napi_value thisVar = nullptr; asyncContext->argc = maxArgs; CHECK_STATUS_RET(napi_get_cb_info(env, info, &asyncContext->argc, &(asyncContext->argv[ARGS_ZERO]), &thisVar, @@ -187,40 +178,31 @@ static napi_status AsyncContextSetStaticObjectInfo(napi_env env, napi_callback_i if (minArgs > 0) { CHECK_COND_RET(asyncContext->argv[ARGS_ZERO] != nullptr, napi_invalid_arg, "Argument list is empty"); } - // 获取context->callbackRef - CHECK_STATUS_RET(PickerNapiUtils::GetParamCallback(env, asyncContext), "Failed to get callback param!"); return napi_ok; } -static napi_value ParseArgsStartDownloadPicker(napi_env env, napi_callback_info info, +static napi_value ParseArgsStartModalPicker(napi_env env, napi_callback_info info, unique_ptr &context) { // 开始解析参数 - HILOG_INFO("lby ParseArgsStartDownloadPicker begin."); + HILOG_INFO("modal picker: ParseArgsStartModalPicker begin."); constexpr size_t minArgs = ARGS_TWO; constexpr size_t maxArgs = ARGS_THREE; CHECK_ARGS(env, AsyncContextSetStaticObjectInfo(env, info, context, minArgs, maxArgs), JS_ERR_PARAMETER_INVALID); - // todo:实现PickerNapiUtils::GetParamCallback - // todo: 这里为什么要设置两次GetParamCallback - NAPI_CALL(env, PickerNapiUtils::GetParamCallback(env, context)); CHECK_NULLPTR_RET(StartPickerExtension(env, info, context)); napi_value result = nullptr; CHECK_ARGS(env, napi_get_boolean(env, true, &result), JS_INNER_FAIL); return result; } -napi_value PickerNExporter::StartDownloadPicker(napi_env env, napi_callback_info info) +napi_value PickerNExporter::StartModalPicker(napi_env env, napi_callback_info info) { - // todo:PickerAsyncContext 理解+拆解 - HILOG_INFO("lby StartDownloadPicker begin."); + HILOG_INFO("modal picker: StartModalPicker begin."); unique_ptr asyncContext = make_unique(); - // asyncContext->resultNapiType = ResultNapiType::TYPE_PHOTOACCESS_HELPER; - // todo: 这里ParseArgsStartDownloadPicker完后已经拉起了UI,NapiCreateAsyncWork的作用 - ParseArgsStartDownloadPicker(env, info, asyncContext); - // todo:实现PickerNapiUtils::NapiCreateAsyncWork - return PickerNapiUtils::NapiCreateAsyncWork(env, asyncContext, "StrartDownloadPicker", - StartDownloadPickerExecute, StartDownloadPickerAsyncCallbackComplete); + ParseArgsStartModalPicker(env, info, asyncContext); + return PickerNapiUtils::NapiCreateAsyncWork(env, asyncContext, "StrartModalPicker", + StartModalPickerExecute, StartModalPickerAsyncCallbackComplete); } PickerNExporter::PickerNExporter(napi_env env, napi_value exports) : NExporter(env, exports) diff --git a/interfaces/kits/picker/src/picker_napi_utils.cpp b/interfaces/kits/picker/src/picker_napi_utils.cpp index 2a28a7ff..c45113b0 100644 --- a/interfaces/kits/picker/src/picker_napi_utils.cpp +++ b/interfaces/kits/picker/src/picker_napi_utils.cpp @@ -60,41 +60,6 @@ void PickerNapiUtils::HandleError(napi_env env, int error, napi_value &errorObj, HILOG_ERROR("Error: %{public}s, js errcode:%{public}d ", errMsg.c_str(), originalError); } -napi_status PickerNapiUtils::GetParamFunction(napi_env env, napi_value arg, napi_ref &callbackRef) -{ - napi_valuetype valueType = napi_undefined; - CHECK_STATUS_RET(napi_typeof(env, arg, &valueType), "Failed to get type"); - CHECK_COND_RET(valueType == napi_function, napi_function_expected, "Type is not as expected function"); - CHECK_STATUS_RET(napi_create_reference(env, arg, NAPI_INIT_REF_COUNT, &callbackRef), "Failed to make callbackref"); - return napi_ok; -} - -napi_status PickerNapiUtils::HasCallback(napi_env env, const size_t argc, const napi_value argv[], - bool &isCallback) -{ - isCallback = false; - if (argc < ARGS_ONE) { - return napi_ok; - } - napi_valuetype valueType = napi_undefined; - CHECK_STATUS_RET(napi_typeof(env, argv[argc - 1], &valueType), "Failed to get type"); - isCallback = (valueType == napi_function); - return napi_ok; -} - -template -napi_status PickerNapiUtils::GetParamCallback(napi_env env, AsyncContext &context) -{ - /* Parse the last argument into callbackref if any */ - bool isCallback = false; - CHECK_STATUS_RET(HasCallback(env, context->argc, context->argv, isCallback), "Failed to check callback"); - if (isCallback) { - CHECK_STATUS_RET(GetParamFunction(env, context->argv[context->argc - 1], context->callbackRef), - "Failed to get callback"); - } - return napi_ok; -} - void PickerNapiUtils::InvokeJSAsyncMethod(napi_env env, napi_deferred deferred, napi_ref callbackRef, napi_async_work work, const JSAsyncContextOutput &asyncContext) { @@ -136,21 +101,6 @@ napi_value PickerNapiUtils::NapiCreateAsyncWork(napi_env env, unique_ptr= E_COMMON_END) { - // error = JS_INNER_FAIL; - // } else if (trans2JsError.count(error)) { - // error = trans2JsError.at(error); - // } - return error; -} - -template napi_status PickerNapiUtils::GetParamCallback>(napi_env env, - unique_ptr &context); - template napi_value PickerNapiUtils::NapiCreateAsyncWork(napi_env env, unique_ptr &asyncContext, const string &resourceName, void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *)); -- Gitee From c3583c8a1d047364295cf2770615987caed66fe7 Mon Sep 17 00:00:00 2001 From: libuyan Date: Wed, 24 Apr 2024 23:06:07 +0800 Subject: [PATCH 04/13] add target Signed-off-by: libuyan --- interfaces/kits/picker/include/picker_n_exporter.h | 3 --- interfaces/kits/picker/src/napi_error.cpp | 1 - interfaces/kits/picker/src/picker_n_exporter.cpp | 3 --- 3 files changed, 7 deletions(-) diff --git a/interfaces/kits/picker/include/picker_n_exporter.h b/interfaces/kits/picker/include/picker_n_exporter.h index 9f56bb87..e852ec15 100644 --- a/interfaces/kits/picker/include/picker_n_exporter.h +++ b/interfaces/kits/picker/include/picker_n_exporter.h @@ -63,9 +63,6 @@ public: PickerNExporter(napi_env env, napi_value exports); ~PickerNExporter() override; }; - -// const std::string RECENT_PATH = "/storage/Users/.Recent/"; -const std::string FILE_ACCESS_PERMISSION = "ohos.permission.FILE_ACCESS_MANAGER"; } // namespace FileAccessFwk } // namespace OHOS #endif // INTERFACES_KITS_NATIVE_PICKER_N_EXPOTER_H diff --git a/interfaces/kits/picker/src/napi_error.cpp b/interfaces/kits/picker/src/napi_error.cpp index 000e1168..6bffd65b 100644 --- a/interfaces/kits/picker/src/napi_error.cpp +++ b/interfaces/kits/picker/src/napi_error.cpp @@ -26,7 +26,6 @@ void NapiError::SetApiName(const std::string &Name) void NapiError::HandleError(napi_env env, napi_value &errorObj) { - // deal with context->error PickerNapiUtils::HandleError(env, error, errorObj, apiName); } diff --git a/interfaces/kits/picker/src/picker_n_exporter.cpp b/interfaces/kits/picker/src/picker_n_exporter.cpp index 6b18ed65..0be0795e 100644 --- a/interfaces/kits/picker/src/picker_n_exporter.cpp +++ b/interfaces/kits/picker/src/picker_n_exporter.cpp @@ -158,12 +158,10 @@ static napi_value StartPickerExtension(napi_env env, napi_callback_info info, } callback->SetSessionId(sessionId); napi_value result = nullptr; - // todo:这里JS_INNER_FAIL未定义 CHECK_ARGS(env, napi_get_boolean(env, true, &result), JS_INNER_FAIL); return result; } -// todo:模板理解+拆解 template static napi_status AsyncContextSetStaticObjectInfo(napi_env env, napi_callback_info info, AsyncContext &asyncContext, const size_t minArgs, const size_t maxArgs) @@ -184,7 +182,6 @@ static napi_status AsyncContextSetStaticObjectInfo(napi_env env, napi_callback_i static napi_value ParseArgsStartModalPicker(napi_env env, napi_callback_info info, unique_ptr &context) { - // 开始解析参数 HILOG_INFO("modal picker: ParseArgsStartModalPicker begin."); constexpr size_t minArgs = ARGS_TWO; constexpr size_t maxArgs = ARGS_THREE; -- Gitee From 0f94f9bd13bd80573dc27aa4092e60a7dcf850c9 Mon Sep 17 00:00:00 2001 From: libuyan Date: Thu, 25 Apr 2024 17:12:32 +0800 Subject: [PATCH 05/13] add target Signed-off-by: libuyan --- interfaces/kits/picker/BUILD.gn | 17 +- .../kits/picker/include/modal_ui_callback.h | 4 +- interfaces/kits/picker/include/napi_error.h | 6 +- .../kits/picker/include/picker_client_errno.h | 2 +- .../kits/picker/include/picker_napi_utils.h | 157 +----------------- .../kits/picker/src/picker_n_exporter.cpp | 58 +++++-- .../kits/picker/src/picker_napi_utils.cpp | 6 +- 7 files changed, 60 insertions(+), 190 deletions(-) diff --git a/interfaces/kits/picker/BUILD.gn b/interfaces/kits/picker/BUILD.gn index 0c8963f2..21745aa8 100644 --- a/interfaces/kits/picker/BUILD.gn +++ b/interfaces/kits/picker/BUILD.gn @@ -13,10 +13,11 @@ import("//build/ohos.gni") import("//build/ohos/ace/ace.gni") -import("//foundation/ability/ability_runtime/ability_runtime.gni") import("../../../../../../arkcompiler/ets_frontend/es2panda/es2abc_config.gni") -import("../../../filemanagement_aafwk.gni") +import( + "../../../../../../foundation/ability/ability_runtime/ability_runtime.gni") import("../../../../../../foundation/arkui/ace_engine/ace_config.gni") +import("../../../filemanagement_aafwk.gni") # compile .js to .abc. action("gen_picker_abc") { @@ -58,16 +59,14 @@ ohos_shared_library("picker") { branch_protector_ret = "pac_ret" ldflags = [ "-Wl" ] - include_dirs = [ - "include", - ] + include_dirs = [ "include" ] sources = [ "native_module_ohos_picker.cpp", "src/modal_ui_callback.cpp", + "src/napi_error.cpp", "src/picker_n_exporter.cpp", "src/picker_napi_utils.cpp", - "src/napi_error.cpp", ] deps = [ @@ -81,18 +80,18 @@ ohos_shared_library("picker") { "ability_runtime:ability_context_native", "ability_runtime:ability_manager", "ability_runtime:abilitykit_native", + "ability_runtime:abilitykit_native", "ability_runtime:app_context", "ability_runtime:dataobs_manager", "ability_runtime:napi_base_context", "ability_runtime:runtime", "ability_runtime:service_extension", "ability_runtime:ui_extension", - "ability_runtime:abilitykit_native", - "napi:ace_napi", + "ace_engine:ace_uicontent", "file_api:filemgmt_libhilog", "file_api:filemgmt_libn", - "ace_engine:ace_uicontent", "hilog:libhilog", + "napi:ace_napi", ] sanitize = { diff --git a/interfaces/kits/picker/include/modal_ui_callback.h b/interfaces/kits/picker/include/modal_ui_callback.h index d7ecd71d..f8c86ae1 100644 --- a/interfaces/kits/picker/include/modal_ui_callback.h +++ b/interfaces/kits/picker/include/modal_ui_callback.h @@ -12,8 +12,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef INTERFACES_KITS_JS_PICKER_INCLUDE_MODAL_UI_CALLBACK_H -#define INTERFACES_KITS_JS_PICKER_INCLUDE_MODAL_UI_CALLBACK_H +#ifndef MODAL_UI_CALLBACK_H +#define MODAL_UI_CALLBACK_H #include "ability_context.h" #include "want.h" diff --git a/interfaces/kits/picker/include/napi_error.h b/interfaces/kits/picker/include/napi_error.h index 31fe1845..8a7aa68a 100644 --- a/interfaces/kits/picker/include/napi_error.h +++ b/interfaces/kits/picker/include/napi_error.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef INTERFACES_KITS_JS_PICKER_INCLUDE_NAPI_ERROR_H_ -#define INTERFACES_KITS_JS_PICKER_INCLUDE_NAPI_ERROR_H_ +#ifndef INTERFACES_KITS_JS_PICKER_INCLUDE_NAPI_ERROR_H +#define INTERFACES_KITS_JS_PICKER_INCLUDE_NAPI_ERROR_H #include #include "napi/native_api.h" @@ -35,4 +35,4 @@ struct NapiError { }; } // namespace Picker } // namespace OHOS -#endif // INTERFACES_KITS_JS_PICKER_INCLUDE_NAPI_ERROR_H_ \ No newline at end of file +#endif // INTERFACES_KITS_JS_PICKER_INCLUDE_NAPI_ERROR_H \ No newline at end of file diff --git a/interfaces/kits/picker/include/picker_client_errno.h b/interfaces/kits/picker/include/picker_client_errno.h index 5153b885..8db0bcf9 100644 --- a/interfaces/kits/picker/include/picker_client_errno.h +++ b/interfaces/kits/picker/include/picker_client_errno.h @@ -64,7 +64,7 @@ constexpr int32_t JS_E_NAMETOOLONG = UFM_JS_ERR(UFM_SYSCAP_BASE, 36); const std::unordered_map jsErrMap = { { JS_ERR_PERMISSION_DENIED, "without permission" }, - { JS_INNER_FAIL, "medialibrary inner fail" }, + { JS_INNER_FAIL, "modal picker inner fail" }, { JS_ERR_PARAMETER_INVALID, "invalid parameter" }, { JS_E_DISPLAYNAME, "display name invalid" }, { JS_ERR_NO_SUCH_FILE, "no such file" }, diff --git a/interfaces/kits/picker/include/picker_napi_utils.h b/interfaces/kits/picker/include/picker_napi_utils.h index 6961a80d..0e9e262f 100644 --- a/interfaces/kits/picker/include/picker_napi_utils.h +++ b/interfaces/kits/picker/include/picker_napi_utils.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef INTERFACES_KITS_JS_PICKER_INCLUDE_PICKER_NAPI_UTILS_H_ -#define INTERFACES_KITS_JS_PICKER_INCLUDE_PICKER_NAPI_UTILS_H_ +#ifndef INTERFACES_KITS_JS_PICKER_INCLUDE_PICKER_NAPI_UTILS_H +#define INTERFACES_KITS_JS_PICKER_INCLUDE_PICKER_NAPI_UTILS_H #include #include @@ -23,156 +23,6 @@ #include "hilog_wrapper.h" #include "picker_client_errno.h" -#ifdef NAPI_ASSERT -#undef NAPI_ASSERT -#endif - -#define CHECK_ARGS_WITH_MESSAGE(env, cond, msg) \ - do { \ - if (!(cond)) { \ - NapiError::ThrowError(env, JS_ERR_PARAMETER_INVALID, __FUNCTION__, __LINE__, msg); \ - return nullptr; \ - } \ - } while (0) - -#define CHECK_COND_WITH_MESSAGE(env, cond, msg) \ - do { \ - if (!(cond)) { \ - NapiError::ThrowError(env, OHOS_INVALID_PARAM_CODE, __FUNCTION__, __LINE__, msg); \ - return nullptr; \ - } \ - } while (0) - -#define NAPI_ASSERT(env, cond, msg) CHECK_ARGS_WITH_MESSAGE(env, cond, msg) - -#define GET_JS_ARGS(env, info, argc, argv, thisVar) \ - do { \ - void *data; \ - napi_get_cb_info(env, info, &(argc), argv, &(thisVar), &(data)); \ - } while (0) - -#define GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar) \ - do { \ - void *data; \ - status = napi_get_cb_info(env, info, nullptr, nullptr, &(thisVar), &(data)); \ - } while (0) - -#define GET_JS_ASYNC_CB_REF(env, arg, count, cbRef) \ - do { \ - napi_valuetype valueType = napi_undefined; \ - if ((napi_typeof(env, arg, &valueType) == napi_ok) && (valueType == napi_function)) { \ - napi_create_reference(env, arg, count, &(cbRef)); \ - } else { \ - HILOG_ERROR("invalid arguments"); \ - NAPI_ASSERT(env, false, "type mismatch"); \ - } \ - } while (0) - -#define ASSERT_NULLPTR_CHECK(env, result) \ - do { \ - if ((result) == nullptr) { \ - napi_get_undefined(env, &(result)); \ - return result; \ - } \ - } while (0) - -#define NAPI_CREATE_PROMISE(env, callbackRef, deferred, result) \ - do { \ - if ((callbackRef) == nullptr) { \ - napi_create_promise(env, &(deferred), &(result)); \ - } \ - } while (0) - -#define NAPI_CREATE_RESOURCE_NAME(env, resource, resourceName, context) \ - do { \ - napi_create_string_utf8(env, resourceName, NAPI_AUTO_LENGTH, &(resource)); \ - (context)->SetApiName(resourceName); \ - } while (0) - -#define CHECK_NULL_PTR_RETURN_UNDEFINED(env, ptr, ret, message) \ - do { \ - if ((ptr) == nullptr) { \ - HILOG_ERROR(message); \ - napi_get_undefined(env, &(ret)); \ - return ret; \ - } \ - } while (0) - -#define CHECK_NULL_PTR_RETURN_VOID(ptr, message) \ - do { \ - if ((ptr) == nullptr) { \ - HILOG_ERROR(message); \ - return; \ - } \ - } while (0) -#define CHECK_IF_EQUAL(condition, errMsg) \ - do { \ - if (!(condition)) { \ - HILOG_ERROR(errMsg); \ - return; \ - } \ - } while (0) - -#define CHECK_COND_RET(cond, ret, message) \ - do { \ - if (!(cond)) { \ - HILOG_ERROR(message); \ - return ret; \ - } \ - } while (0) - -#define CHECK_STATUS_RET(cond, message) \ - do { \ - napi_status __ret = (cond); \ - if (__ret != napi_ok) { \ - HILOG_ERROR(message); \ - return __ret; \ - } \ - } while (0) - -#define CHECK_NULLPTR_RET(ret) \ - do { \ - if ((ret) == nullptr) { \ - return nullptr; \ - } \ - } while (0) - -#define CHECK_ARGS_BASE(env, cond, err, retVal) \ - do { \ - if ((cond) != napi_ok) { \ - NapiError::ThrowError(env, err, __FUNCTION__, __LINE__); \ - return retVal; \ - } \ - } while (0) - -#define CHECK_ARGS(env, cond, err) CHECK_ARGS_BASE(env, cond, err, nullptr) - -#define CHECK_ARGS_THROW_INVALID_PARAM(env, cond) CHECK_ARGS(env, cond, OHOS_INVALID_PARAM_CODE) - -#define CHECK_ARGS_RET_VOID(env, cond, err) CHECK_ARGS_BASE(env, cond, err, NAPI_RETVAL_NOTHING) - -#define CHECK_COND(env, cond, err) \ - do { \ - if (!(cond)) { \ - NapiError::ThrowError(env, err, __FUNCTION__, __LINE__); \ - return nullptr; \ - } \ - } while (0) - -#define RETURN_NAPI_TRUE(env) \ - do { \ - napi_value result = nullptr; \ - CHECK_ARGS(env, napi_get_boolean(env, true, &result), JS_INNER_FAIL); \ - return result; \ - } while (0) - -#define RETURN_NAPI_UNDEFINED(env) \ - do { \ - napi_value result = nullptr; \ - CHECK_ARGS(env, napi_get_undefined(env, &result), JS_INNER_FAIL); \ - return result; \ - } while (0) - namespace OHOS { namespace Picker { /* Constants for array index */ @@ -228,5 +78,4 @@ public: } // namespace Picker } // namespace OHOS - -#endif // INTERFACES_KITS_JS_PICKER_INCLUDE_PICKER_NAPI_UTILS_H_ +#endif // INTERFACES_KITS_JS_PICKER_INCLUDE_PICKER_NAPI_UTILS_H diff --git a/interfaces/kits/picker/src/picker_n_exporter.cpp b/interfaces/kits/picker/src/picker_n_exporter.cpp index 0be0795e..3a789335 100644 --- a/interfaces/kits/picker/src/picker_n_exporter.cpp +++ b/interfaces/kits/picker/src/picker_n_exporter.cpp @@ -59,19 +59,27 @@ static void StartModalPickerAsyncCallbackComplete(napi_env env, napi_status stat { HILOG_INFO("modal picker: StartModalPickerAsyncCallbackComplete begin."); auto *context = static_cast(data); - CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null"); + if (context == nullptr) { + HILOG_ERROR("Async context is null"); + return; + } auto jsContext = make_unique(); jsContext->status = false; - CHECK_ARGS_RET_VOID(env, napi_get_undefined(env, &jsContext->data), JS_ERR_PARAMETER_INVALID); - CHECK_ARGS_RET_VOID(env, napi_get_undefined(env, &jsContext->error), JS_ERR_PARAMETER_INVALID); - + status = napi_get_undefined(env, &jsContext->data); + if (status != napi_ok) { + HILOG_ERROR("modal picker: napi_get_undefined jsContext->data failed"); + } + status = napi_get_undefined(env, &jsContext->error); + if (status != napi_ok) { + HILOG_ERROR("modal picker: napi_get_undefined jsContext->error failed"); + } const string uri = context->pickerCallBack->uri; HILOG_DEBUG("modal picker: uri is %{public}s.", uri.c_str()); napi_value jsUri = nullptr; - CHECK_ARGS_RET_VOID(env, napi_create_string_utf8(env, uri.c_str(), - NAPI_AUTO_LENGTH, &jsUri), JS_INNER_FAIL); + status = napi_create_string_utf8(env, uri.c_str(), NAPI_AUTO_LENGTH, &jsUri); + if (jsUri == nullptr) { HILOG_ERROR("jsUri is nullptr."); } @@ -143,7 +151,8 @@ static napi_value StartPickerExtension(napi_env env, napi_callback_info info, auto callback = std::make_shared(uiContent, AsyncContext->pickerCallBack.get()); Ace::ModalUIExtensionCallbacks extensionCallback = { .onRelease = std::bind(&ModalUICallback::OnRelease, callback, std::placeholders::_1), - .onResult = std::bind(&ModalUICallback::OnResultForModal, callback, std::placeholders::_1, std::placeholders::_2), + .onResult = std::bind(&ModalUICallback::OnResultForModal, callback, std::placeholders::_1, + std::placeholders::_2), .onReceive = std::bind(&ModalUICallback::OnReceive, callback, std::placeholders::_1), .onError = std::bind(&ModalUICallback::OnError, callback, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), @@ -153,12 +162,12 @@ static napi_value StartPickerExtension(napi_env env, napi_callback_info info, HILOG_INFO("modal picker: will CreateModalUIExtension by extType: %{public}s, pickerType: %{public}s", targetType.c_str(), pickerType.c_str()); int sessionId = uiContent->CreateModalUIExtension(request, extensionCallback, config); if (sessionId == 0) { - HILOG_ERROR("modal picker create modalUIExtension failed"); + HILOG_ERROR("modal picker: create modalUIExtension failed"); return nullptr; } callback->SetSessionId(sessionId); napi_value result = nullptr; - CHECK_ARGS(env, napi_get_boolean(env, true, &result), JS_INNER_FAIL); + napi_get_boolean(env, true, &result); return result; } @@ -169,12 +178,20 @@ static napi_status AsyncContextSetStaticObjectInfo(napi_env env, napi_callback_i HILOG_INFO("modal picker: AsyncContextSetStaticObjectInfo begin."); napi_value thisVar = nullptr; asyncContext->argc = maxArgs; - CHECK_STATUS_RET(napi_get_cb_info(env, info, &asyncContext->argc, &(asyncContext->argv[ARGS_ZERO]), &thisVar, - nullptr), "Failed to get cb info"); - CHECK_COND_RET(((asyncContext->argc >= minArgs) && (asyncContext->argc <= maxArgs)), napi_invalid_arg, - "Number of args is invalid"); + napi_status ret = napi_get_cb_info(env, info, &asyncContext->argc, &(asyncContext->argv[ARGS_ZERO]), &thisVar, nullptr); + if (ret != napi_ok) { + HILOG_ERROR("modal picker: Failed to get cb info"); + return ret; + } + if (!((asyncContext->argc >= minArgs) && (asyncContext->argc <= maxArgs))) { + HILOG_ERROR("modal picker: Number of args is invalid"); + return napi_invalid_arg; + } if (minArgs > 0) { - CHECK_COND_RET(asyncContext->argv[ARGS_ZERO] != nullptr, napi_invalid_arg, "Argument list is empty"); + if (asyncContext->argv[ARGS_ZERO] == nullptr) { + HILOG_ERROR("modal picker: Argument list is empty"); + return napi_invalid_arg; + } } return napi_ok; } @@ -185,11 +202,16 @@ static napi_value ParseArgsStartModalPicker(napi_env env, napi_callback_info inf HILOG_INFO("modal picker: ParseArgsStartModalPicker begin."); constexpr size_t minArgs = ARGS_TWO; constexpr size_t maxArgs = ARGS_THREE; - CHECK_ARGS(env, AsyncContextSetStaticObjectInfo(env, info, context, minArgs, maxArgs), - JS_ERR_PARAMETER_INVALID); - CHECK_NULLPTR_RET(StartPickerExtension(env, info, context)); + napi_status status = AsyncContextSetStaticObjectInfo(env, info, context, minArgs, maxArgs); + if (status != napi_ok) { + HILOG_ERROR("modal picker: AsyncContextSetStaticObjectInfo faild"); + } + napi_value ret = StartPickerExtension(env, info, context); + if ((ret) == nullptr) { + return nullptr; + } napi_value result = nullptr; - CHECK_ARGS(env, napi_get_boolean(env, true, &result), JS_INNER_FAIL); + napi_get_boolean(env, true, &result); return result; } diff --git a/interfaces/kits/picker/src/picker_napi_utils.cpp b/interfaces/kits/picker/src/picker_napi_utils.cpp index c45113b0..2a8be5ad 100644 --- a/interfaces/kits/picker/src/picker_napi_utils.cpp +++ b/interfaces/kits/picker/src/picker_napi_utils.cpp @@ -90,9 +90,9 @@ napi_value PickerNapiUtils::NapiCreateAsyncWork(napi_env env, unique_ptrcallbackRef, asyncContext->deferred, result); - NAPI_CREATE_RESOURCE_NAME(env, resource, resourceName.c_str(), asyncContext); - + napi_create_promise(env, &(asyncContext->deferred), &(result)); + napi_create_string_utf8(env, resourceName.c_str(), NAPI_AUTO_LENGTH, &(resource)); + asyncContext->SetApiName(resourceName.c_str()); NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, execute, complete, static_cast(asyncContext.get()), &asyncContext->work)); NAPI_CALL(env, napi_queue_async_work(env, asyncContext->work)); -- Gitee From 3d0549a62f20c41ae40bd763a1159bad4b8f6a6b Mon Sep 17 00:00:00 2001 From: libuyan Date: Thu, 25 Apr 2024 17:15:07 +0800 Subject: [PATCH 06/13] add target Signed-off-by: libuyan --- interfaces/kits/picker/include/napi_error.h | 2 +- interfaces/kits/picker/include/picker_client_errno.h | 2 +- interfaces/kits/picker/include/picker_napi_utils.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/interfaces/kits/picker/include/napi_error.h b/interfaces/kits/picker/include/napi_error.h index 8a7aa68a..190be9fb 100644 --- a/interfaces/kits/picker/include/napi_error.h +++ b/interfaces/kits/picker/include/napi_error.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021-2022 Huawei Device Co., Ltd. + * Copyright (C) 2024 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 diff --git a/interfaces/kits/picker/include/picker_client_errno.h b/interfaces/kits/picker/include/picker_client_errno.h index 8db0bcf9..26a91cc3 100644 --- a/interfaces/kits/picker/include/picker_client_errno.h +++ b/interfaces/kits/picker/include/picker_client_errno.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021-2022 Huawei Device Co., Ltd. + * Copyright (C) 2024 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 diff --git a/interfaces/kits/picker/include/picker_napi_utils.h b/interfaces/kits/picker/include/picker_napi_utils.h index 0e9e262f..54d67614 100644 --- a/interfaces/kits/picker/include/picker_napi_utils.h +++ b/interfaces/kits/picker/include/picker_napi_utils.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021-2022 Huawei Device Co., Ltd. + * Copyright (C) 2024 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 -- Gitee From 2bd1d7ceae2e8d0f8f0cad46242131a71aa8c7fa Mon Sep 17 00:00:00 2001 From: libuyan Date: Thu, 25 Apr 2024 21:49:01 +0800 Subject: [PATCH 07/13] add target Signed-off-by: libuyan --- interfaces/kits/picker/BUILD.gn | 3 - .../kits/picker/include/modal_ui_callback.h | 2 +- interfaces/kits/picker/include/napi_error.h | 38 --------- .../kits/picker/include/picker_client_errno.h | 83 ------------------- .../kits/picker/include/picker_n_exporter.h | 6 +- .../kits/picker/include/picker_napi_utils.h | 2 - .../kits/picker/native_module_ohos_picker.cpp | 2 +- .../kits/picker/src/modal_ui_callback.cpp | 2 +- interfaces/kits/picker/src/napi_error.cpp | 62 -------------- .../kits/picker/src/picker_n_exporter.cpp | 20 +++-- .../kits/picker/src/picker_napi_utils.cpp | 21 +---- 11 files changed, 17 insertions(+), 224 deletions(-) delete mode 100644 interfaces/kits/picker/include/napi_error.h delete mode 100644 interfaces/kits/picker/include/picker_client_errno.h delete mode 100644 interfaces/kits/picker/src/napi_error.cpp diff --git a/interfaces/kits/picker/BUILD.gn b/interfaces/kits/picker/BUILD.gn index 21745aa8..ebbbefa2 100644 --- a/interfaces/kits/picker/BUILD.gn +++ b/interfaces/kits/picker/BUILD.gn @@ -14,8 +14,6 @@ import("//build/ohos.gni") import("//build/ohos/ace/ace.gni") import("../../../../../../arkcompiler/ets_frontend/es2panda/es2abc_config.gni") -import( - "../../../../../../foundation/ability/ability_runtime/ability_runtime.gni") import("../../../../../../foundation/arkui/ace_engine/ace_config.gni") import("../../../filemanagement_aafwk.gni") @@ -64,7 +62,6 @@ ohos_shared_library("picker") { sources = [ "native_module_ohos_picker.cpp", "src/modal_ui_callback.cpp", - "src/napi_error.cpp", "src/picker_n_exporter.cpp", "src/picker_napi_utils.cpp", ] diff --git a/interfaces/kits/picker/include/modal_ui_callback.h b/interfaces/kits/picker/include/modal_ui_callback.h index f8c86ae1..eef34d8c 100644 --- a/interfaces/kits/picker/include/modal_ui_callback.h +++ b/interfaces/kits/picker/include/modal_ui_callback.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Huawei Device Co., Ltd. + * Copyright (C) 2024 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 diff --git a/interfaces/kits/picker/include/napi_error.h b/interfaces/kits/picker/include/napi_error.h deleted file mode 100644 index 190be9fb..00000000 --- a/interfaces/kits/picker/include/napi_error.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef INTERFACES_KITS_JS_PICKER_INCLUDE_NAPI_ERROR_H -#define INTERFACES_KITS_JS_PICKER_INCLUDE_NAPI_ERROR_H - -#include -#include "napi/native_api.h" -#include "napi/native_node_api.h" -#include "picker_napi_utils.h" - -namespace OHOS { -namespace Picker { -#define EXPORT __attribute__ ((visibility ("default"))) -struct NapiError { - int32_t error = 0; - std::string apiName; - void SetApiName(const std::string &Name); - void HandleError(napi_env env, napi_value &errorObj); - EXPORT static void ThrowError(napi_env env, int32_t err, const std::string &errMsg = ""); - EXPORT static void ThrowError(napi_env env, int32_t err, const char *func, int32_t line, - const std::string &errMsg = ""); -}; -} // namespace Picker -} // namespace OHOS -#endif // INTERFACES_KITS_JS_PICKER_INCLUDE_NAPI_ERROR_H \ No newline at end of file diff --git a/interfaces/kits/picker/include/picker_client_errno.h b/interfaces/kits/picker/include/picker_client_errno.h deleted file mode 100644 index 26a91cc3..00000000 --- a/interfaces/kits/picker/include/picker_client_errno.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef OHOS_PICKER_CLIENT_ERRNO_H -#define OHOS_PICKER_CLIENT_ERRNO_H - -#include -#include - - -namespace OHOS { -namespace Picker { -constexpr int32_t FILEIO_MODULE_CODE = 139; -constexpr int32_t UFM_MODULE_CODE = 140; -constexpr int32_t UFM_SYSCAP_BASE = 202; - -constexpr int32_t OHOS_PERMISSION_DENIED_CODE = 201; -constexpr int32_t OHOS_INVALID_PARAM_CODE = 401; - -#define MODULE_OFFSET 100000 -#define MODULE_CODE(code) (((code) * MODULE_OFFSET)) -#define UFM_JS_ERR(moduleCode, errCode) ((MODULE_CODE(moduleCode)) + (errCode)) - -//JS_INNER_FAIL JS_ERR_PARAMETER_INVALID -// file io common error code -constexpr int32_t JS_ERR_NO_SUCH_FILE = UFM_JS_ERR(FILEIO_MODULE_CODE, 2); // no such file -constexpr int32_t JS_ERR_NO_MEM = UFM_JS_ERR(FILEIO_MODULE_CODE, 11); // cannot allocate memory -constexpr int32_t JS_ERR_PERMISSION_DENIED = UFM_JS_ERR(FILEIO_MODULE_CODE, 12); // permission deny -constexpr int32_t JS_ERR_FILE_EXIST = UFM_JS_ERR(FILEIO_MODULE_CODE, 15); // file has exist -constexpr int32_t JS_ERR_PARAMETER_INVALID = UFM_JS_ERR(FILEIO_MODULE_CODE, 20); // input parameter invalid - -// userfileMananger error code -constexpr int32_t JS_E_DISPLAYNAME = UFM_JS_ERR(UFM_MODULE_CODE, 1); -constexpr int32_t JS_E_URI = UFM_JS_ERR(UFM_MODULE_CODE, 2); -constexpr int32_t JS_E_FILE_EXTENSION = UFM_JS_ERR(UFM_MODULE_CODE, 3); -constexpr int32_t JS_E_TRASHED = UFM_JS_ERR(UFM_MODULE_CODE, 4); -constexpr int32_t JS_E_OPEN_MODE = UFM_JS_ERR(UFM_MODULE_CODE, 5); -constexpr int32_t JS_E_NOT_ALBUM = UFM_JS_ERR(UFM_MODULE_CODE, 6); -constexpr int32_t JS_E_ROOT_DIR = UFM_JS_ERR(UFM_MODULE_CODE, 7); -constexpr int32_t JS_E_MOVE_DENIED = UFM_JS_ERR(UFM_MODULE_CODE, 8); -constexpr int32_t JS_E_RENAME_DENIED = UFM_JS_ERR(UFM_MODULE_CODE, 9); -constexpr int32_t JS_E_RELATIVEPATH = UFM_JS_ERR(UFM_MODULE_CODE, 10); -constexpr int32_t JS_INNER_FAIL = UFM_JS_ERR(UFM_MODULE_CODE, 11); -// file type is not allow in the directory -constexpr int32_t JS_E_FILE_TYPE = UFM_JS_ERR(UFM_MODULE_CODE, 12); -constexpr int32_t JS_E_NO_MEMORY = UFM_JS_ERR(UFM_MODULE_CODE, 13); // no memory left -constexpr int32_t JS_E_FILE_KEY = UFM_JS_ERR(UFM_MODULE_CODE, 14); // wrong member name -constexpr int32_t JS_E_INPUT = UFM_JS_ERR(UFM_MODULE_CODE, 15); -// media change request error -constexpr int32_t JS_E_OPERATION_NOT_SUPPORT = UFM_JS_ERR(UFM_MODULE_CODE, 16); -constexpr int32_t JS_E_NAMETOOLONG = UFM_JS_ERR(UFM_SYSCAP_BASE, 36); - -const std::unordered_map jsErrMap = { - { JS_ERR_PERMISSION_DENIED, "without permission" }, - { JS_INNER_FAIL, "modal picker inner fail" }, - { JS_ERR_PARAMETER_INVALID, "invalid parameter" }, - { JS_E_DISPLAYNAME, "display name invalid" }, - { JS_ERR_NO_SUCH_FILE, "no such file" }, - { JS_ERR_FILE_EXIST, "file has existed" }, - { JS_E_FILE_TYPE, "file type is not allow in the directory" }, - { JS_E_FILE_KEY, "member not exist" }, - { JS_ERR_NO_MEM, "cannot allocate memory" }, - { JS_E_NAMETOOLONG, "file name is too long" }, - { OHOS_PERMISSION_DENIED_CODE, "Permission denied" }, - { OHOS_INVALID_PARAM_CODE, "invalid parameter" }, -}; -} // namespace Picker -} // namespace OHOS - - -#endif // OHOS_PICKER_CLIENT_ERRNO_H diff --git a/interfaces/kits/picker/include/picker_n_exporter.h b/interfaces/kits/picker/include/picker_n_exporter.h index e852ec15..1d5dc365 100644 --- a/interfaces/kits/picker/include/picker_n_exporter.h +++ b/interfaces/kits/picker/include/picker_n_exporter.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * Copyright (c) 2024 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 @@ -22,10 +22,8 @@ #include "data_ability_predicates.h" #include "filemgmt_libn.h" #include "picker_napi_utils.h" -#include "napi_error.h" #include "napi_base_context.h" #include "napi_common_want.h" -#include "picker_client_errno.h" namespace OHOS { @@ -45,7 +43,7 @@ struct PickerCallBack { string uri; }; -struct PickerAsyncContext : public NapiError { +struct PickerAsyncContext { napi_async_work work; napi_deferred deferred; napi_ref callbackRef; diff --git a/interfaces/kits/picker/include/picker_napi_utils.h b/interfaces/kits/picker/include/picker_napi_utils.h index 54d67614..47418156 100644 --- a/interfaces/kits/picker/include/picker_napi_utils.h +++ b/interfaces/kits/picker/include/picker_napi_utils.h @@ -21,7 +21,6 @@ #include "napi/native_api.h" #include "napi/native_node_api.h" #include "hilog_wrapper.h" -#include "picker_client_errno.h" namespace OHOS { namespace Picker { @@ -65,7 +64,6 @@ struct NapiClassInfo { /* Util class used by napi asynchronous methods for making call to js callback function */ class PickerNapiUtils { public: - static void HandleError(napi_env env, int error, napi_value &errorObj, const std::string &Name); static void CreateNapiErrorObject(napi_env env, napi_value &errorObj, const int32_t errCode, const std::string errMsg); static void InvokeJSAsyncMethod(napi_env env, napi_deferred deferred, napi_ref callbackRef, napi_async_work work, diff --git a/interfaces/kits/picker/native_module_ohos_picker.cpp b/interfaces/kits/picker/native_module_ohos_picker.cpp index 8547fc81..f0041fd9 100644 --- a/interfaces/kits/picker/native_module_ohos_picker.cpp +++ b/interfaces/kits/picker/native_module_ohos_picker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Huawei Device Co., Ltd. + * Copyright (C) 2023-2024 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 diff --git a/interfaces/kits/picker/src/modal_ui_callback.cpp b/interfaces/kits/picker/src/modal_ui_callback.cpp index 7ac2b9c6..97140dec 100644 --- a/interfaces/kits/picker/src/modal_ui_callback.cpp +++ b/interfaces/kits/picker/src/modal_ui_callback.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Huawei Device Co., Ltd. + * Copyright (C) 2024 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 diff --git a/interfaces/kits/picker/src/napi_error.cpp b/interfaces/kits/picker/src/napi_error.cpp deleted file mode 100644 index 6bffd65b..00000000 --- a/interfaces/kits/picker/src/napi_error.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "napi_error.h" - -using namespace std; - -namespace OHOS { -namespace Picker { -void NapiError::SetApiName(const std::string &Name) -{ - apiName = Name; -} - -void NapiError::HandleError(napi_env env, napi_value &errorObj) -{ - PickerNapiUtils::HandleError(env, error, errorObj, apiName); -} - -void NapiError::ThrowError(napi_env env, int32_t err, const std::string &errMsg) -{ - string message = errMsg; - if (message.empty()) { - message = "operation not support"; - if (jsErrMap.count(err) > 0) { - message = jsErrMap.at(err); - } - } - - HILOG_ERROR("ThrowError errCode:%{public}d errMsg:%{public}s", err, message.c_str()); - NAPI_CALL_RETURN_VOID(env, napi_throw_error(env, to_string(err).c_str(), message.c_str())); -} - -void NapiError::ThrowError(napi_env env, int32_t err, const char *funcName, int32_t line, const std::string &errMsg) -{ - string message = errMsg; - if (message.empty()) { - message = "operation not support"; - if (jsErrMap.count(err) > 0) { - message = jsErrMap.at(err); - } - } - - HILOG_ERROR("{%{public}s:%d} ThrowError errCode:%{public}d errMsg:%{public}s", funcName, line, - err, message.c_str()); - NAPI_CALL_RETURN_VOID(env, napi_throw_error(env, to_string(err).c_str(), message.c_str())); -} - -} // namespace Picker -} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/picker/src/picker_n_exporter.cpp b/interfaces/kits/picker/src/picker_n_exporter.cpp index 3a789335..5127b3d3 100644 --- a/interfaces/kits/picker/src/picker_n_exporter.cpp +++ b/interfaces/kits/picker/src/picker_n_exporter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * Copyright (c) 2024 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 @@ -153,13 +153,14 @@ static napi_value StartPickerExtension(napi_env env, napi_callback_info info, .onRelease = std::bind(&ModalUICallback::OnRelease, callback, std::placeholders::_1), .onResult = std::bind(&ModalUICallback::OnResultForModal, callback, std::placeholders::_1, std::placeholders::_2), - .onReceive = std::bind(&ModalUICallback::OnReceive, callback, std::placeholders::_1), + .onReceive = std::bind(&ModalUICallback::OnReceive, callback, std::placeholders::_1), .onError = std::bind(&ModalUICallback::OnError, callback, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), .onDestroy = std::bind(&ModalUICallback::OnDestroy, callback), }; Ace::ModalUIExtensionConfig config; - HILOG_INFO("modal picker: will CreateModalUIExtension by extType: %{public}s, pickerType: %{public}s", targetType.c_str(), pickerType.c_str()); + HILOG_INFO("modal picker: will CreateModalUIExtension by extType: %{public}s, pickerType: %{public}s", + targetType.c_str(), pickerType.c_str()); int sessionId = uiContent->CreateModalUIExtension(request, extensionCallback, config); if (sessionId == 0) { HILOG_ERROR("modal picker: create modalUIExtension failed"); @@ -178,17 +179,18 @@ static napi_status AsyncContextSetStaticObjectInfo(napi_env env, napi_callback_i HILOG_INFO("modal picker: AsyncContextSetStaticObjectInfo begin."); napi_value thisVar = nullptr; asyncContext->argc = maxArgs; - napi_status ret = napi_get_cb_info(env, info, &asyncContext->argc, &(asyncContext->argv[ARGS_ZERO]), &thisVar, nullptr); + napi_status ret = napi_get_cb_info(env, info, &asyncContext->argc, &(asyncContext->argv[ARGS_ZERO]), + &thisVar, nullptr); if (ret != napi_ok) { HILOG_ERROR("modal picker: Failed to get cb info"); return ret; - } - if (!((asyncContext->argc >= minArgs) && (asyncContext->argc <= maxArgs))) { + } + if (!((asyncContext->argc >= minArgs) && (asyncContext->argc <= maxArgs))) { HILOG_ERROR("modal picker: Number of args is invalid"); return napi_invalid_arg; } if (minArgs > 0) { - if (asyncContext->argv[ARGS_ZERO] == nullptr) { + if (asyncContext->argv[ARGS_ZERO] == nullptr) { HILOG_ERROR("modal picker: Argument list is empty"); return napi_invalid_arg; } @@ -207,9 +209,9 @@ static napi_value ParseArgsStartModalPicker(napi_env env, napi_callback_info inf HILOG_ERROR("modal picker: AsyncContextSetStaticObjectInfo faild"); } napi_value ret = StartPickerExtension(env, info, context); - if ((ret) == nullptr) { + if (ret == nullptr) { return nullptr; - } + } napi_value result = nullptr; napi_get_boolean(env, true, &result); return result; diff --git a/interfaces/kits/picker/src/picker_napi_utils.cpp b/interfaces/kits/picker/src/picker_napi_utils.cpp index 2a8be5ad..fa806c30 100644 --- a/interfaces/kits/picker/src/picker_napi_utils.cpp +++ b/interfaces/kits/picker/src/picker_napi_utils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2024 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 @@ -42,24 +42,6 @@ void PickerNapiUtils::CreateNapiErrorObject(napi_env env, napi_value &errorObj, } } -void PickerNapiUtils::HandleError(napi_env env, int error, napi_value &errorObj, const string &Name) -{ - if (error == ERR_DEFAULT) { - return; - } - - string errMsg = "System inner fail"; - int originalError = error; - if (jsErrMap.count(error) > 0) { - errMsg = jsErrMap.at(error); - } else { - error = JS_INNER_FAIL; - } - CreateNapiErrorObject(env, errorObj, error, errMsg); - errMsg = Name + " " + errMsg; - HILOG_ERROR("Error: %{public}s, js errcode:%{public}d ", errMsg.c_str(), originalError); -} - void PickerNapiUtils::InvokeJSAsyncMethod(napi_env env, napi_deferred deferred, napi_ref callbackRef, napi_async_work work, const JSAsyncContextOutput &asyncContext) { @@ -92,7 +74,6 @@ napi_value PickerNapiUtils::NapiCreateAsyncWork(napi_env env, unique_ptrdeferred), &(result)); napi_create_string_utf8(env, resourceName.c_str(), NAPI_AUTO_LENGTH, &(resource)); - asyncContext->SetApiName(resourceName.c_str()); NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, execute, complete, static_cast(asyncContext.get()), &asyncContext->work)); NAPI_CALL(env, napi_queue_async_work(env, asyncContext->work)); -- Gitee From dcd5fb865a4c717a3246fddff8dcd28502d69dd9 Mon Sep 17 00:00:00 2001 From: libuyan Date: Thu, 25 Apr 2024 22:46:34 +0800 Subject: [PATCH 08/13] add target Signed-off-by: libuyan --- interfaces/kits/picker/BUILD.gn | 1 - interfaces/kits/picker/picker.js | 14 +++++++------- interfaces/kits/picker/src/picker_n_exporter.cpp | 8 ++++---- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/interfaces/kits/picker/BUILD.gn b/interfaces/kits/picker/BUILD.gn index ebbbefa2..664cb8ae 100644 --- a/interfaces/kits/picker/BUILD.gn +++ b/interfaces/kits/picker/BUILD.gn @@ -14,7 +14,6 @@ import("//build/ohos.gni") import("//build/ohos/ace/ace.gni") import("../../../../../../arkcompiler/ets_frontend/es2panda/es2abc_config.gni") -import("../../../../../../foundation/arkui/ace_engine/ace_config.gni") import("../../../filemanagement_aafwk.gni") # compile .js to .abc. diff --git a/interfaces/kits/picker/picker.js b/interfaces/kits/picker/picker.js index 6ca0e2ee..638e1d30 100644 --- a/interfaces/kits/picker/picker.js +++ b/interfaces/kits/picker/picker.js @@ -29,7 +29,7 @@ const DocumentSelectMode = { MIXED: 2, }; -const DocumentSaveMode = { +const DocumentPickerMode = { DEFAULT: 0, DOWNLOAD: 1, }; @@ -344,7 +344,7 @@ function parseDocumentPickerSaveOption(args, action) { action: action, parameters: { startMode: 'save', - pickerMode: DocumentSaveMode.DEFAULT, + pickerMode: DocumentPickerMode.DEFAULT, } }; @@ -361,7 +361,7 @@ function parseDocumentPickerSaveOption(args, action) { if ((option.fileSuffixChoices !== undefined) && option.fileSuffixChoices.length > 0) { config.parameters.key_file_suffix_choices = option.fileSuffixChoices; } - if (option.pickerMode === DocumentSaveMode.DOWNLOAD) { + if (option.pickerMode === DocumentPickerMode.DOWNLOAD) { config.parameters.pickerMode = option.pickerMode; config.action = ACTION.SAVE_ACTION_DOWNLOAD; config.parameters.extType = ExtTypes.DOWNLOAD_TYPE; @@ -429,7 +429,7 @@ function startModalPicker(context, config) { console.log('modal picker: pickerHelper undefined.') } let helper = pickerHelper.startModalPicker(gContext, config); - if (helper !== undefined) { + if (helper === undefined) { console.log('modal picker: startModalPicker helper undefined.'); } return helper; @@ -472,7 +472,7 @@ async function documentPickerSave(...args) { } documentSaveConfig = parseDocumentPickerSaveOption(args, ACTION.SAVE_ACTION_MODAL); - if (documentSaveConfig.parameters.pickerMode === DocumentSaveMode.DOWNLOAD) { + if (documentSaveConfig.parameters.pickerMode === DocumentPickerMode.DOWNLOAD) { console.log('modal picker: will start modal picker process. (DOWNLOAD)'); modalPicker(args, documentSaveContext, documentSaveConfig); return; @@ -583,7 +583,7 @@ function DocumentSaveOptions() { this.newFileNames = undefined; this.defaultFilePathUri = undefined; this.fileSuffixChoices = undefined; - this.pickerMode = DocumentSaveMode.DEFAULT; + this.pickerMode = DocumentPickerMode.DEFAULT; } function AudioSelectOptions() {} @@ -616,7 +616,7 @@ export default { PhotoSelectResult : PhotoSelectResult, PhotoSaveOptions : PhotoSaveOptions, DocumentSelectMode : DocumentSelectMode, - DocumentSaveMode : DocumentSaveMode, + DocumentPickerMode : DocumentPickerMode, DocumentSelectOptions : DocumentSelectOptions, DocumentSaveOptions : DocumentSaveOptions, AudioSelectOptions : AudioSelectOptions, diff --git a/interfaces/kits/picker/src/picker_n_exporter.cpp b/interfaces/kits/picker/src/picker_n_exporter.cpp index 5127b3d3..05b94190 100644 --- a/interfaces/kits/picker/src/picker_n_exporter.cpp +++ b/interfaces/kits/picker/src/picker_n_exporter.cpp @@ -151,15 +151,15 @@ static napi_value StartPickerExtension(napi_env env, napi_callback_info info, auto callback = std::make_shared(uiContent, AsyncContext->pickerCallBack.get()); Ace::ModalUIExtensionCallbacks extensionCallback = { .onRelease = std::bind(&ModalUICallback::OnRelease, callback, std::placeholders::_1), - .onResult = std::bind(&ModalUICallback::OnResultForModal, callback, std::placeholders::_1, + .onResult = std::bind(&ModalUICallback::OnResultForModal, callback, std::placeholders::_1, std::placeholders::_2), - .onReceive = std::bind(&ModalUICallback::OnReceive, callback, std::placeholders::_1), + .onReceive = std::bind(&ModalUICallback::OnReceive, callback, std::placeholders::_1), .onError = std::bind(&ModalUICallback::OnError, callback, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), .onDestroy = std::bind(&ModalUICallback::OnDestroy, callback), }; Ace::ModalUIExtensionConfig config; - HILOG_INFO("modal picker: will CreateModalUIExtension by extType: %{public}s, pickerType: %{public}s", + HILOG_INFO("modal picker: will CreateModalUIExtension by extType: %{public}s, pickerType: %{public}s", targetType.c_str(), pickerType.c_str()); int sessionId = uiContent->CreateModalUIExtension(request, extensionCallback, config); if (sessionId == 0) { @@ -179,7 +179,7 @@ static napi_status AsyncContextSetStaticObjectInfo(napi_env env, napi_callback_i HILOG_INFO("modal picker: AsyncContextSetStaticObjectInfo begin."); napi_value thisVar = nullptr; asyncContext->argc = maxArgs; - napi_status ret = napi_get_cb_info(env, info, &asyncContext->argc, &(asyncContext->argv[ARGS_ZERO]), + napi_status ret = napi_get_cb_info(env, info, &asyncContext->argc, &(asyncContext->argv[ARGS_ZERO]), &thisVar, nullptr); if (ret != napi_ok) { HILOG_ERROR("modal picker: Failed to get cb info"); -- Gitee From dc65dca72991274b639743a7bd7b1dee750c7767 Mon Sep 17 00:00:00 2001 From: libuyan Date: Fri, 26 Apr 2024 10:11:40 +0800 Subject: [PATCH 09/13] add target Signed-off-by: libuyan --- interfaces/kits/picker/picker.js | 32 +++++++++++-------- .../kits/picker/src/picker_n_exporter.cpp | 7 ++-- .../kits/picker/src/picker_napi_utils.cpp | 20 +++--------- 3 files changed, 27 insertions(+), 32 deletions(-) diff --git a/interfaces/kits/picker/picker.js b/interfaces/kits/picker/picker.js index 638e1d30..808497be 100644 --- a/interfaces/kits/picker/picker.js +++ b/interfaces/kits/picker/picker.js @@ -436,21 +436,25 @@ function startModalPicker(context, config) { } async function modalPicker(args, context, config) { - console.log('modal picker: config: ' + JSON.stringify(config)); - let modalSaveResult = await startModalPicker(context, config); - const saveResult = getModalPickerResult(modalSaveResult); - if (args.length === ARGS_TWO && typeof args[ARGS_ONE] === 'function') { - return args[ARGS_ONE](saveResult.error, saveResult.data); - } else if (args.length === ARGS_ONE && typeof args[ARGS_ZERO] === 'function') { - return args[ARGS_ZERO](saveResult.error, saveResult.data); - } - return new Promise((resolve, reject) => { - if (saveResult.data !== undefined) { - resolve(saveResult.data); - } else { - reject(saveResult.error); + try { + console.log('modal picker: config: ' + JSON.stringify(config)); + let modalSaveResult = await startModalPicker(context, config); + const saveResult = getModalPickerResult(modalSaveResult); + if (args.length === ARGS_TWO && typeof args[ARGS_ONE] === 'function') { + return args[ARGS_ONE](saveResult.error, saveResult.data); + } else if (args.length === ARGS_ONE && typeof args[ARGS_ZERO] === 'function') { + return args[ARGS_ZERO](saveResult.error, saveResult.data); } - }) + return new Promise((resolve, reject) => { + if (saveResult.data !== undefined) { + resolve(saveResult.data); + } else { + reject(saveResult.error); + } + }) + } catch (resultError) { + console.error('modal picker: Result error: ' + resultError); + } } async function documentPickerSave(...args) { diff --git a/interfaces/kits/picker/src/picker_n_exporter.cpp b/interfaces/kits/picker/src/picker_n_exporter.cpp index 05b94190..740f4fc9 100644 --- a/interfaces/kits/picker/src/picker_n_exporter.cpp +++ b/interfaces/kits/picker/src/picker_n_exporter.cpp @@ -208,11 +208,11 @@ static napi_value ParseArgsStartModalPicker(napi_env env, napi_callback_info inf if (status != napi_ok) { HILOG_ERROR("modal picker: AsyncContextSetStaticObjectInfo faild"); } + napi_value result = nullptr; napi_value ret = StartPickerExtension(env, info, context); if (ret == nullptr) { return nullptr; } - napi_value result = nullptr; napi_get_boolean(env, true, &result); return result; } @@ -221,7 +221,10 @@ napi_value PickerNExporter::StartModalPicker(napi_env env, napi_callback_info in { HILOG_INFO("modal picker: StartModalPicker begin."); unique_ptr asyncContext = make_unique(); - ParseArgsStartModalPicker(env, info, asyncContext); + napi_value ret = ParseArgsStartModalPicker(env, info, asyncContext); + if (ret == nullptr) { + return nullptr; + } return PickerNapiUtils::NapiCreateAsyncWork(env, asyncContext, "StrartModalPicker", StartModalPickerExecute, StartModalPickerAsyncCallbackComplete); } diff --git a/interfaces/kits/picker/src/picker_napi_utils.cpp b/interfaces/kits/picker/src/picker_napi_utils.cpp index fa806c30..2f8c391b 100644 --- a/interfaces/kits/picker/src/picker_napi_utils.cpp +++ b/interfaces/kits/picker/src/picker_napi_utils.cpp @@ -45,23 +45,11 @@ void PickerNapiUtils::CreateNapiErrorObject(napi_env env, napi_value &errorObj, void PickerNapiUtils::InvokeJSAsyncMethod(napi_env env, napi_deferred deferred, napi_ref callbackRef, napi_async_work work, const JSAsyncContextOutput &asyncContext) { - napi_value retVal; - napi_value callback = nullptr; - - /* Deferred is used when JS Callback method expects a promise value */ - if (deferred) { - if (asyncContext.status) { - napi_resolve_deferred(env, deferred, asyncContext.data); - } else { - napi_reject_deferred(env, deferred, asyncContext.error); - } + HILOG_INFO("modal picker: InvokeJSAsyncMethod begin.") + if (asyncContext.status) { + napi_resolve_deferred(env, deferred, asyncContext.data); } else { - napi_value result[ARGS_TWO]; - result[PARAM0] = asyncContext.error; - result[PARAM1] = asyncContext.data; - napi_get_reference_value(env, callbackRef, &callback); - napi_call_function(env, nullptr, callback, ARGS_TWO, result, &retVal); - napi_delete_reference(env, callbackRef); + napi_reject_deferred(env, deferred, asyncContext.error); } napi_delete_async_work(env, work); } -- Gitee From f5a3cdcf2ceab983c8667c29bfb517e12cc929f6 Mon Sep 17 00:00:00 2001 From: libuyan Date: Fri, 26 Apr 2024 10:25:50 +0800 Subject: [PATCH 10/13] add target Signed-off-by: libuyan --- interfaces/kits/picker/src/picker_napi_utils.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interfaces/kits/picker/src/picker_napi_utils.cpp b/interfaces/kits/picker/src/picker_napi_utils.cpp index 2f8c391b..32d251d9 100644 --- a/interfaces/kits/picker/src/picker_napi_utils.cpp +++ b/interfaces/kits/picker/src/picker_napi_utils.cpp @@ -45,7 +45,7 @@ void PickerNapiUtils::CreateNapiErrorObject(napi_env env, napi_value &errorObj, void PickerNapiUtils::InvokeJSAsyncMethod(napi_env env, napi_deferred deferred, napi_ref callbackRef, napi_async_work work, const JSAsyncContextOutput &asyncContext) { - HILOG_INFO("modal picker: InvokeJSAsyncMethod begin.") + HILOG_INFO("modal picker: InvokeJSAsyncMethod begin."); if (asyncContext.status) { napi_resolve_deferred(env, deferred, asyncContext.data); } else { -- Gitee From 5b7c58f449611e61c06dd490cd93ef05fbb02b3b Mon Sep 17 00:00:00 2001 From: libuyan Date: Sun, 28 Apr 2024 10:26:09 +0800 Subject: [PATCH 11/13] add target Signed-off-by: libuyan --- interfaces/kits/picker/include/picker_n_exporter.h | 1 - 1 file changed, 1 deletion(-) diff --git a/interfaces/kits/picker/include/picker_n_exporter.h b/interfaces/kits/picker/include/picker_n_exporter.h index 1d5dc365..09f58890 100644 --- a/interfaces/kits/picker/include/picker_n_exporter.h +++ b/interfaces/kits/picker/include/picker_n_exporter.h @@ -38,7 +38,6 @@ struct NameListArg { struct PickerCallBack { bool ready = false; - bool isOrigin; int32_t resultCode; string uri; }; -- Gitee From 36b25ad1062989584cf6c8cb5b2710e3f9380b3c Mon Sep 17 00:00:00 2001 From: libuyan Date: Sun, 28 Apr 2024 22:53:31 +0800 Subject: [PATCH 12/13] add target Signed-off-by: libuyan --- interfaces/kits/picker/picker.js | 57 ++++++++++++++------------------ 1 file changed, 24 insertions(+), 33 deletions(-) diff --git a/interfaces/kits/picker/picker.js b/interfaces/kits/picker/picker.js index 808497be..514f8fba 100644 --- a/interfaces/kits/picker/picker.js +++ b/interfaces/kits/picker/picker.js @@ -378,8 +378,10 @@ function getModalPickerResult(args) { error: undefined, data: undefined } - if (args) { - saveResult.data = args.uri; + if (args && args.uri) { + var dataArr = []; + dataArr.push(args.uri); + saveResult.data = dataArr; } console.log('modal picker: download saveResult: ' + JSON.stringify(saveResult)); return saveResult; @@ -440,18 +442,7 @@ async function modalPicker(args, context, config) { console.log('modal picker: config: ' + JSON.stringify(config)); let modalSaveResult = await startModalPicker(context, config); const saveResult = getModalPickerResult(modalSaveResult); - if (args.length === ARGS_TWO && typeof args[ARGS_ONE] === 'function') { - return args[ARGS_ONE](saveResult.error, saveResult.data); - } else if (args.length === ARGS_ONE && typeof args[ARGS_ZERO] === 'function') { - return args[ARGS_ZERO](saveResult.error, saveResult.data); - } - return new Promise((resolve, reject) => { - if (saveResult.data !== undefined) { - resolve(saveResult.data); - } else { - reject(saveResult.error); - } - }) + return saveResult; } catch (resultError) { console.error('modal picker: Result error: ' + resultError); } @@ -467,6 +458,7 @@ async function documentPickerSave(...args) { let documentSaveContext = undefined; let documentSaveConfig = undefined; let documentSaveResult = undefined; + let saveResult = undefined; try { documentSaveContext = getContext(this); @@ -478,29 +470,28 @@ async function documentPickerSave(...args) { documentSaveConfig = parseDocumentPickerSaveOption(args, ACTION.SAVE_ACTION_MODAL); if (documentSaveConfig.parameters.pickerMode === DocumentPickerMode.DOWNLOAD) { console.log('modal picker: will start modal picker process. (DOWNLOAD)'); - modalPicker(args, documentSaveContext, documentSaveConfig); - return; - } - - try { - if (documentSaveContext === undefined) { - throw getErr(ErrCode.CONTEXT_NO_EXIST); - } - documentSaveConfig = parseDocumentPickerSaveOption(args, ACTION.SAVE_ACTION_MODAL); - documentSaveResult = await documentSaveContext.requestDialogService(documentSaveConfig); - } catch (paramError) { - console.error('[picker] paramError: ' + JSON.stringify(paramError)); + saveResult = await modalPicker(args, documentSaveContext, documentSaveConfig); + } else { try { - documentSaveConfig = parseDocumentPickerSaveOption(args, ACTION.SAVE_ACTION); - documentSaveResult = await documentSaveContext.startAbilityForResult(documentSaveConfig, {windowMode: 0}); - } catch (error) { - console.error('[picker] document save error: ' + error); - return undefined; + if (documentSaveContext === undefined) { + throw getErr(ErrCode.CONTEXT_NO_EXIST); + } + documentSaveConfig = parseDocumentPickerSaveOption(args, ACTION.SAVE_ACTION_MODAL); + documentSaveResult = await documentSaveContext.requestDialogService(documentSaveConfig); + } catch (paramError) { + console.error('[picker] paramError: ' + JSON.stringify(paramError)); + try { + documentSaveConfig = parseDocumentPickerSaveOption(args, ACTION.SAVE_ACTION); + documentSaveResult = await documentSaveContext.startAbilityForResult(documentSaveConfig, {windowMode: 0}); + } catch (error) { + console.error('[picker] document save error: ' + error); + return undefined; + } } + console.log('[picker] document save result: ' + JSON.stringify(documentSaveResult)); + saveResult = getDocumentPickerSaveResult(documentSaveResult); } - console.log('[picker] document save result: ' + JSON.stringify(documentSaveResult)); try { - const saveResult = getDocumentPickerSaveResult(documentSaveResult); if (args.length === ARGS_TWO && typeof args[ARGS_ONE] === 'function') { return args[ARGS_ONE](saveResult.error, saveResult.data); } else if (args.length === ARGS_ONE && typeof args[ARGS_ZERO] === 'function') { -- Gitee From 8c9713bcccc43338e890abfae90b6eb4ca5cd123 Mon Sep 17 00:00:00 2001 From: libuyan Date: Sun, 28 Apr 2024 23:44:55 +0800 Subject: [PATCH 13/13] add target Signed-off-by: libuyan --- interfaces/kits/picker/picker.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interfaces/kits/picker/picker.js b/interfaces/kits/picker/picker.js index 514f8fba..85681b7f 100644 --- a/interfaces/kits/picker/picker.js +++ b/interfaces/kits/picker/picker.js @@ -378,7 +378,7 @@ function getModalPickerResult(args) { error: undefined, data: undefined } - if (args && args.uri) { + if (args) { var dataArr = []; dataArr.push(args.uri); saveResult.data = dataArr; -- Gitee