From ca02a1468b3f93bc5dc137d0f9da1480e6850c88 Mon Sep 17 00:00:00 2001 From: txazo Date: Sat, 15 Jun 2024 11:13:38 +0800 Subject: [PATCH 01/10] =?UTF-8?q?=E5=85=83=E6=9C=8D=E5=8A=A1=E6=96=B0?= =?UTF-8?q?=E5=A2=9EAtomicServiceWeb=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: txazo --- advanced_ui_component/BUILD.gn | 1 + .../atomicserviceweb/interfaces/BUILD.gn | 66 + .../interfaces/api_policy_adapter.cpp | 42 + .../interfaces/atomicserviceweb.cpp | 126 ++ .../interfaces/atomicserviceweb.js | 1087 ++++++++++++++++ .../interfaces/include/api_policy_adapter.h | 27 + .../source/atomicserviceweb.ets | 1146 +++++++++++++++++ 7 files changed, 2495 insertions(+) create mode 100644 advanced_ui_component/atomicserviceweb/interfaces/BUILD.gn create mode 100644 advanced_ui_component/atomicserviceweb/interfaces/api_policy_adapter.cpp create mode 100644 advanced_ui_component/atomicserviceweb/interfaces/atomicserviceweb.cpp create mode 100644 advanced_ui_component/atomicserviceweb/interfaces/atomicserviceweb.js create mode 100644 advanced_ui_component/atomicserviceweb/interfaces/include/api_policy_adapter.h create mode 100644 advanced_ui_component/atomicserviceweb/source/atomicserviceweb.ets diff --git a/advanced_ui_component/BUILD.gn b/advanced_ui_component/BUILD.gn index efe443e1a5d..5b2356b0376 100644 --- a/advanced_ui_component/BUILD.gn +++ b/advanced_ui_component/BUILD.gn @@ -16,6 +16,7 @@ group("advanced_ui_component") { "arcslider/interfaces:arcslider", "atomicservicenavigation/interfaces:atomicservicenavigation", "atomicservicetabs/interfaces:atomicservicetabs", + "atomicserviceweb/interfaces:atomicserviceweb", "chip/interfaces:chip", "chipgroup/interfaces:chipgroup", "composelistitem/interfaces:composelistitem", diff --git a/advanced_ui_component/atomicserviceweb/interfaces/BUILD.gn b/advanced_ui_component/atomicserviceweb/interfaces/BUILD.gn new file mode 100644 index 00000000000..2338cb7b74a --- /dev/null +++ b/advanced_ui_component/atomicserviceweb/interfaces/BUILD.gn @@ -0,0 +1,66 @@ +# 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. + +import("//arkcompiler/ets_frontend/es2panda/es2abc_config.gni") +import("//build/ohos.gni") +import("//foundation/arkui/ace_engine/ace_config.gni") +import("//foundation/arkui/ace_engine/adapter/preview/build/config.gni") +import("//foundation/arkui/ace_engine/build/ace_gen_obj.gni") + +es2abc_gen_abc("gen_atomicserviceweb_abc") { + src_js = rebase_path("atomicserviceweb.js") + dst_file = rebase_path(target_out_dir + "/atomicserviceweb.abc") + in_puts = [ "atomicserviceweb.js" ] + out_puts = [ target_out_dir + "/atomicserviceweb.abc" ] + extra_args = [ "--module" ] +} + +gen_js_obj("atomicserviceweb_js") { + input = "atomicserviceweb.js" + output = target_out_dir + "/atomicserviceweb.o" +} + +gen_js_obj("atomicserviceweb_abc") { + input = get_label_info(":gen_atomicserviceweb_abc", "target_out_dir") + + "/atomicserviceweb.abc" + output = target_out_dir + "/atomicserviceweb_abc.o" + dep = ":gen_atomicserviceweb_abc" +} + +gen_obj("atomicserviceweb_abc_preview") { + input = get_label_info(":gen_atomicserviceweb_abc", "target_out_dir") + + "/atomicserviceweb.abc" + output = target_out_dir + "/atomicserviceweb_abc.c" + snapshot_dep = [ ":gen_atomicserviceweb_abc" ] +} + +ohos_shared_library("atomicserviceweb") { + include_dirs = [ "include" ] + + sources = [ "atomicserviceweb.cpp", "api_policy_adapter.cpp" ] + + if (use_mingw_win || use_mac || use_linux) { + deps = [ ":gen_obj_src_atomicserviceweb_abc_preview" ] + } else { + deps = [ ":atomicserviceweb_js", ":atomicserviceweb_abc" ] + } + + external_deps = [ + "hilog:libhilog", + "napi:ace_napi", + ] + + relative_install_dir = "module/atomicservice" + subsystem_name = ace_engine_subsystem + part_name = ace_engine_part +} diff --git a/advanced_ui_component/atomicserviceweb/interfaces/api_policy_adapter.cpp b/advanced_ui_component/atomicserviceweb/interfaces/api_policy_adapter.cpp new file mode 100644 index 00000000000..6c0cfbb0601 --- /dev/null +++ b/advanced_ui_component/atomicserviceweb/interfaces/api_policy_adapter.cpp @@ -0,0 +1,42 @@ +/* + * 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. + */ + +#include "../include/api_policy_adapter.h" +#include + +ApiPolicyAdapter::ApiPolicyAdapter() { + handle = dlopen("/system/lib64/platformsdk/libapipolicy_client.z.so", RTLD_NOW); + if (!handle) { + return; + } +} + +ApiPolicyAdapter::~ApiPolicyAdapter() { + if (handle) { + dlclose(handle); + handle = nullptr; + } +} + +int32_t ApiPolicyAdapter::CheckUrl(std::string bundleName, std::string domainType, std::string url) { + int32_t res = -1; + using CheckUrl = int32_t (*)(std::string, std::string, std::string); + auto func = reinterpret_cast(dlsym(handle, "CheckUrl")); + if (func == nullptr) { + return res; + } + res = func(bundleName, domainType, url); + return res; +} diff --git a/advanced_ui_component/atomicserviceweb/interfaces/atomicserviceweb.cpp b/advanced_ui_component/atomicserviceweb/interfaces/atomicserviceweb.cpp new file mode 100644 index 00000000000..d5a1ffe6e44 --- /dev/null +++ b/advanced_ui_component/atomicserviceweb/interfaces/atomicserviceweb.cpp @@ -0,0 +1,126 @@ +/* + * 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. + */ + +#include "native_engine/native_engine.h" +#include "napi/native_api.h" +#include "napi/native_node_api.h" +#include "../include/api_policy_adapter.h" + +using namespace std; + +extern const char _binary_atomicserviceweb_js_start[]; +extern const char _binary_atomicserviceweb_js_end[]; +extern const char _binary_atomicserviceweb_abc_start[]; +extern const char _binary_atomicserviceweb_abc_end[]; + +namespace HMS::AtomicServiceWeb { + static napi_value CheckUrl(napi_env env, napi_callback_info info) + { + size_t requireArgc = 3; + size_t argc = 3; + napi_value args[3] = { nullptr }; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr)); + + NAPI_ASSERT(env, argc >= requireArgc, "Wrong number of arguments"); + + napi_valuetype valuetype0; + NAPI_CALL(env, napi_typeof(env, args[0], &valuetype0)); + + napi_valuetype valuetype1; + NAPI_CALL(env, napi_typeof(env, args[1], &valuetype1)); + + napi_valuetype valuetype2; + NAPI_CALL(env, napi_typeof(env, args[2], &valuetype2)); + + NAPI_ASSERT(env, valuetype0 == napi_string && valuetype1 == napi_string && valuetype2 == napi_string, "Wrong argument type. String expected."); + + size_t maxValueLen = 1024; + char value0[maxValueLen]; + size_t length0 = 0; + napi_get_value_string_utf8(env, args[0], value0, maxValueLen, &length0); + std::string strValue0 = value0; + + char value1[maxValueLen]; + size_t length1 = 0; + napi_get_value_string_utf8(env, args[1], value1, maxValueLen, &length1); + std::string strValue1 = value1; + + char value2[maxValueLen]; + size_t length2 = 0; + napi_get_value_string_utf8(env, args[2], value2, maxValueLen, &length2); + std::string strValue2 = value2; + + auto apiPolicyAdapter = new ApiPolicyAdapter(); + int32_t res = apiPolicyAdapter->CheckUrl(strValue0, strValue1, strValue2); + + napi_value result; + NAPI_CALL(env, napi_create_double(env, res, &result)); + return result; + } + + static napi_value Init(napi_env env, napi_value exports) + { + napi_property_descriptor desc[] = { + DECLARE_NAPI_FUNCTION("checkUrl", CheckUrl), + }; + NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc)); + return exports; + } + + // Napi get js code function + extern "C" __attribute__((visibility("default"))) + void NAPI_atomicservice_AtomicServiceWeb_GetJSCode(const char **buf, int *buflen) + { + if (buf != nullptr) { + *buf = _binary_atomicserviceweb_js_start; + } + if (buflen != nullptr) { + *buflen = _binary_atomicserviceweb_js_end - _binary_atomicserviceweb_js_start; + } + } + + // Napi get abc code function + extern "C" __attribute__((visibility("default"))) + void NAPI_atomicservice_AtomicServiceWeb_GetABCCode(const char **buf, int *buflen) + { + if (buf != nullptr) { + *buf = _binary_atomicserviceweb_abc_start; + } + if (buflen != nullptr) { + *buflen = _binary_atomicserviceweb_abc_end - _binary_atomicserviceweb_abc_start; + } + } + + /* + * Module define + */ + static napi_module AtomicServiceWebModule = { + .nm_version = 1, + .nm_flags = 0, + .nm_filename = nullptr, + .nm_register_func = Init, + .nm_modname = "atomicservice.AtomicServiceWeb", + .nm_priv = ((void*)0), + .reserved = { 0 }, + }; + + /* + * Module registerfunction + */ + extern "C" __attribute__((constructor)) void AtomicServiceWebRegisterModule(void) + { + napi_module_register(&AtomicServiceWebModule); + } +} diff --git a/advanced_ui_component/atomicserviceweb/interfaces/atomicserviceweb.js b/advanced_ui_component/atomicserviceweb/interfaces/atomicserviceweb.js new file mode 100644 index 00000000000..222a372baba --- /dev/null +++ b/advanced_ui_component/atomicserviceweb/interfaces/atomicserviceweb.js @@ -0,0 +1,1087 @@ +/* + * 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. + */ + +if (!("finalizeConstruction" in ViewPU.prototype)) { + Reflect.set(ViewPU.prototype, "finalizeConstruction", () => { + }); +} +const web_webview = requireNapi('web.webview'); +const router = requireNapi('router'); +const deviceInfo = requireNapi('deviceInfo'); +const geoLocationManager = requireNapi('geoLocationManager'); +const bundleManager = requireNapi('bundle.bundleManager'); +const abilityAccessCtrl = requireNapi('abilityAccessCtrl'); +const connection = requireNapi('net.connection'); +const request = requireNapi('request'); +const fs = requireNapi('file.fs'); +const util = requireNapi('util'); +const photoAccessHelper = requireNapi('file.photoAccessHelper'); +const filePreview = globalThis.requireNapi('filemanagement.filepreview', false, '', 'hms'); +const fileUri = requireNapi('file.fileuri'); +const picker = requireNapi('multimedia.cameraPicker'); +const filePicker = requireNapi('file.picker'); +const atomicServiceWebNapi = requireInternal('atomicservice.AtomicServiceWeb'); + +class Error { + constructor(e11, f11) { + this.code = e11; + this.message = f11; + } +} + +class JsApiConfig { + constructor(a11, b11, c11, d11) { + this.apiName = a11; + this.minVersion = b11; + this.maxVersion = c11; + this.requiredFieldNames = d11; + } +} + +const LOG_ENABLE = true; +const LOG_PREFIX = '[AtomicServiceWebLog]'; +const UPLOAD_IMAGE_CACHE_DIR = '/cache/'; +const JAVA_SCRIPT_PROXY_OBJECT_NAME = 'atomicServiceProxy'; +const JAVA_SCRIPT_PROXY_API_NAME_LIST = ['invokeJsApi']; +const ATOMIC_SERVICE_JS_API_MAP = new Map(); +const registerJsApi = (v10, w10, x10, y10, z10) => { + ATOMIC_SERVICE_JS_API_MAP.set(v10, new JsApiConfig(w10, x10, y10, z10)); +}; +const MAX_VERSION = '99.99.99'; +const ATOMIC_SERVICE_JS_SDK_CURRENT_VERSION = '1.0.0'; +const PERMISSION_APPROXIMATELY_LOCATION = 'ohos.permission.APPROXIMATELY_LOCATION'; +const SYSTEM_INTERNAL_ERROR = new Error(500, 'System internal error.'); +const JS_API_INVALID_INVOKE_ERROR = new Error(200001, 'Invalid invoke.'); +const PARAM_REQUIRED_ERROR_CODE = 200002; +const PARAM_NUMBER_POSITIVE_ERROR_CODE = 200003; +const ROUTER_PARAM_MODE_INVALID_ERROR = new Error(200004, 'Param mode is invalid.'); +const BACK_URL_NOT_EXIST_OR_OPENED_ERROR = new Error(200005, 'Url is not exist or opened, can not be back.'); +const NAV_PATH_STACK_NOT_EXIST_ERROR_CODE = 200006; +const POP_PATH_NAME_NOT_EXIST_ERROR = new Error(200007, 'Name is not exist or opened, can not be pop.'); +const POP_PATH_PARAM_INDEX_INVALID_ERROR = new Error(200008, 'Param index is invalid.'); +const POP_PATH_INDEX_OUT_OF_RANGE_ERROR = new Error(200009, 'The Index is out of range.'); +const UPLOAD_IMAGE_FILES_REQUIRED_ERROR = new Error(200010, 'Param files is required.'); +const UPLOAD_IMAGE_FILE_NOT_EXIST_ERROR_CODE = 200011; +const UPLOAD_IMAGE_FILES_URI_REQUIRED_ERROR = new Error(200012, 'Param uri of files is required.'); +const UPLOAD_FILE_ERROR = new Error(200013, 'Upload file error.'); +const IMAGE_CAN_NOT_PREVIEW_ERROR = new Error(200014, 'The filePath can not preview.'); +const NETWORK_NO_ACTIVE_ERROR = new Error(200015, 'The network is not active.'); +{ + registerJsApi('router.pushUrl', 'pushUrl', '1.0.0', MAX_VERSION, ['url']); + registerJsApi('router.replaceUrl', 'replaceUrl', '1.0.0', MAX_VERSION, ['url']); + registerJsApi('router.back', 'backUrl', '1.0.0', MAX_VERSION, []); + registerJsApi('router.clear', 'clearUrl', '1.0.0', MAX_VERSION, []); + registerJsApi('navPathStack.pushPath', 'pushPath', '1.0.0', MAX_VERSION, ['name']); + registerJsApi('navPathStack.replacePath', 'replacePath', '1.0.0', MAX_VERSION, ['name']); + registerJsApi('navPathStack.pop', 'popPath', '1.0.0', MAX_VERSION, []); + registerJsApi('navPathStack.clear', 'clearPath', '1.0.0', MAX_VERSION, []); + registerJsApi('asWeb.postMessage', 'postMessage', '1.0.0', MAX_VERSION, ['data']); + registerJsApi('asWeb.getEnv', 'getEnv', '1.0.0', MAX_VERSION, []); + registerJsApi('asWeb.checkJsApi', 'checkJsApi', '1.0.0', MAX_VERSION, ['jsApiList']); + registerJsApi('cameraPicker.pick', 'pickCamera', '1.0.0', MAX_VERSION, ['mediaTypes', 'cameraPosition']); + registerJsApi('photoViewPicker.select', 'selectPhoto', '1.0.0', MAX_VERSION, []); + registerJsApi('filePreview.openPreview', 'openPreview', '1.0.0', MAX_VERSION, ['uri']); + registerJsApi('request.uploadFile', 'uploadFile', '1.0.0', MAX_VERSION, ['url', 'files']); + registerJsApi('request.downloadFile', 'downloadFile', '1.0.0', MAX_VERSION, ['url']); + registerJsApi('connection.getNetworkType', 'getNetworkType', '1.0.0', MAX_VERSION, []); + registerJsApi('location.getLocation', 'getLocation', '1.0.0', MAX_VERSION, []); +} + +export class AtomicServiceWeb extends ViewPU { + constructor(o10, p10, q10, r10 = -1, s10 = undefined, t10) { + super(o10, q10, r10, t10); + if (typeof s10 === "function") { + this.paramsGenerator_ = s10; + } + this.__src = new SynchedPropertyObjectOneWayPU(p10.src, this, "src"); + this.navPathStack = undefined; + this.onMessage = () => { + }; + this.context = getContext(this); + this.controller = new web_webview.WebviewController(); + this.schemeHandler = new web_webview.WebSchemeHandler(); + this.atomicService = undefined; + this.atomicServiceProxy = undefined; + this.setInitiallyProvidedValue(p10); + this.finalizeConstruction(); + } + + setInitiallyProvidedValue(n10) { + if (n10.navPathStack !== undefined) { + this.navPathStack = n10.navPathStack; + } + if (n10.onMessage !== undefined) { + this.onMessage = n10.onMessage; + } + if (n10.context !== undefined) { + this.context = n10.context; + } + if (n10.controller !== undefined) { + this.controller = n10.controller; + } + if (n10.schemeHandler !== undefined) { + this.schemeHandler = n10.schemeHandler; + } + if (n10.atomicService !== undefined) { + this.atomicService = n10.atomicService; + } + if (n10.atomicServiceProxy !== undefined) { + this.atomicServiceProxy = n10.atomicServiceProxy; + } + } + + updateStateVars(m10) { + this.__src.reset(m10.src); + } + + purgeVariableDependenciesOnElmtId(l10) { + this.__src.purgeDependencyOnElmtId(l10); + } + + aboutToBeDeleted() { + this.__src.aboutToBeDeleted(); + SubscriberManager.Get().delete(this.id__()); + this.aboutToBeDeletedInternal(); + } + + get src() { + return this.__src.get(); + } + + set src(k10) { + this.__src.set(k10); + } + + aboutToAppear() { + if (!this.atomicService) { + this.atomicService = new AtomicServiceApi(this.context, this.navPathStack, this.onMessage); + this.atomicServiceProxy = new AtomicServiceProxy(this.atomicService); + } + } + + aboutToDisappear() { + this.atomicService?.notifyMessage(); + } + + initialRender() { + this.observeComponentCreation2((b10, c10) => { + Web.create({ src: this.src, controller: this.controller }); + Web.fileAccess(true); + Web.imageAccess(true); + Web.onlineImageAccess(true); + Web.javaScriptAccess(true); + Web.domStorageAccess(true); + Web.geolocationAccess(true); + Web.onControllerAttached(() => { + this.registerJavaScriptProxy(); + this.schemeHandler.onRequestStart((j10) => { + return !this.checkUrl(j10.getRequestUrl()); + }); + this.controller.setWebSchemeHandler('https', this.schemeHandler); + }); + Web.onOverrideUrlLoading((h10) => { + return !this.checkUrl(h10.getRequestUrl()); + }); + Web.onLoadIntercept(g10 => { + return !this.checkUrl(g10.data.getRequestUrl()); + }); + }, Web); + } + + registerJavaScriptProxy() { + try { + this.controller.registerJavaScriptProxy(this.atomicServiceProxy, JAVA_SCRIPT_PROXY_OBJECT_NAME, JAVA_SCRIPT_PROXY_API_NAME_LIST); + } catch (y9) { + let z9 = y9; + console.error(`AtomicServiceWeb registerJavaScriptProxy failed, code is ${z9.code}, message is ${z9.message}`); + } + } + + cutUrl(q1) { + if (q1) { + let a2 = q1.indexOf('?'); + if (a2 > -1) { + return q1.substring(0, a2); + } + } + return q1; + } + + checkUrl(q1) { + if (!q1) { + return false; + } + if (q1.startsWith('resource://rawfile')) { + return true; + } + try { + let w1 = this.context.abilityInfo.bundleName; + let t1 = 'webView'; + q1 = this.cutUrl(q1); + let res = atomicServiceWebNapi.checkUrl(w1, t1, q1); + console.log(`AtomicServiceWeb checkUrl res=${res} bundleName=${w1} domainType=${t1} url=${q1}`); + return res === 0; + } catch (j2) { + let n2 = j2; + console.error(`AtomicServiceWeb checkUrl failed, code is ${n2.code}, message is ${n2.message}`); + return false; + } + } + + rerender() { + this.updateDirtyElements(); + } +} + +class AtomicServiceProxy { + constructor(r9) { + this.atomicService = r9; + } + + invokeJsApi(m9, n9) { + try { + n9 = n9 || {}; + if (!m9 || !ATOMIC_SERVICE_JS_API_MAP.has(m9)) { + this.atomicService.errorWithCodeAndMsg(JS_API_INVALID_INVOKE_ERROR, n9); + return; + } + this.atomicService.logOptions(m9, n9); + let p9 = ATOMIC_SERVICE_JS_API_MAP.get(m9); + if (!this.atomicService.checkRequiredFieldInOptions(p9, n9)) { + return; + } + let q9 = this.atomicService; + q9[p9?.apiName](n9); + } catch (o9) { + this.atomicService.error(o9, n9); + } + } +} + +class AtomicService { + constructor(i9, j9, k9) { + this.messageDataList = []; + this.onMessage = () => { + }; + this.context = i9; + this.navPathStack = j9; + this.onMessage = k9 ? k9 : this.onMessage; + } + + success(g9, h9) { + h9?.callback && h9?.callback(undefined, g9); + } + + error(e9, f9) { + f9?.callback && f9?.callback(new Error(e9.code ? e9.code : SYSTEM_INTERNAL_ERROR.code, e9.message ? e9.message : SYSTEM_INTERNAL_ERROR.message)); + } + + errorWithCodeAndMsg(c9, d9) { + d9?.callback && d9?.callback(c9); + } + + consoleLog(b9) { + if (LOG_ENABLE) { + console.log(`${LOG_PREFIX} ${b9}`); + } + } + + consoleError(a9) { + if (LOG_ENABLE) { + console.error(`${LOG_PREFIX} ${a9}`); + } + } + + logOptions(y8, z8) { + this.consoleLog(`${y8} options=${JSON.stringify(z8)}`); + } + + checkParamRequired(v8, w8, x8) { + if (w8 === undefined || w8 === null || w8 === '') { + this.errorWithCodeAndMsg(new Error(PARAM_REQUIRED_ERROR_CODE, `Param ${v8} is required.`), x8); + return false; + } + return true; + } + + checkNumberParamPositive(s8, t8, u8) { + if (t8 <= 0) { + this.errorWithCodeAndMsg(new Error(PARAM_NUMBER_POSITIVE_ERROR_CODE, `Param ${s8} must be a positive number.`), u8); + return false; + } + return true; + } + + checkRequiredFieldInOptions(n8, o8) { + if (!n8) { + return false; + } + if (!n8.requiredFieldNames) { + return true; + } + let p8 = o8; + for (let i3 = 0; i3 < n8.requiredFieldNames.length; i3++) { + let m3 = n8.requiredFieldNames[i3]; + if (!this.checkParamRequired(m3, p8[m3], o8)) { + return false; + } + } + return true; + } + + checkRouterMode(l8, m8) { + if (!l8 || l8 === 'Single' || l8 === 'Standard') { + return true; + } + this.errorWithCodeAndMsg(ROUTER_PARAM_MODE_INVALID_ERROR, m8); + return false; + } + + parseRouterMode(k8) { + return k8 === 'Single' ? router.RouterMode.Single : router.RouterMode.Standard; + } + + getRouterIndexByDelta(g8) { + let h8 = parseInt(router.getLength()); + for (let i8 = h8; i8 > 0; i8--) { + let j8 = router.getStateByIndex(i8); + if (j8?.name && g8-- == 0) { + return i8; + } + } + return 1; + } + + checkBackUrlExists(a8, b8) { + let c8 = parseInt(router.getLength()); + for (let d8 = c8; d8 > 0; d8--) { + let e8 = router.getStateByIndex(d8); + if (e8?.name) { + let f8 = e8?.path + e8?.name; + if (f8 === a8) { + return true; + } + } + } + this.errorWithCodeAndMsg(BACK_URL_NOT_EXIST_OR_OPENED_ERROR, b8); + return false; + } + + checkNavPathStack(y7, z7) { + if (!this.navPathStack) { + this.errorWithCodeAndMsg(new Error(NAV_PATH_STACK_NOT_EXIST_ERROR_CODE, `Current page is not NavDestination, not support ${y7}().`), z7); + return false; + } + return true; + } + + getNavPathIndexByDelta(w7) { + let x7 = this.navPathStack?.getAllPathName(); + if (!x7 || x7.length == 0) { + return -1; + } + return x7.length > w7 ? (x7.length - w7 - 1) : -1; + } + + onPopHandler(u7, v7) { + if (!u7?.info || !v7) { + return; + } + v7(new OnPopEvent(u7.info.name, u7.info.param, u7.result)); + } + + getCurrentNavPathInfo() { + let s7 = this.navPathStack?.getAllPathName(); + let t7 = (s7 && s7.length > 0) ? new NavPathInfo(s7[s7.length - 1], s7.length - 1) : + new NavPathInfo(undefined, -1); + if (t7.index >= 0) { + t7.param = this.navPathStack?.getParamByIndex(t7.index); + } + return t7; + } + + notifyMessage() { + if (this.messageDataList.length <= 0) { + return; + } + this.onMessage({ data: this.messageDataList }); + this.messageDataList = []; + } + + isJsApiEnable(q7) { + if (!q7) { + return false; + } + if (this.compareVersion(q7.minVersion, ATOMIC_SERVICE_JS_SDK_CURRENT_VERSION) && + this.compareVersion(ATOMIC_SERVICE_JS_SDK_CURRENT_VERSION, q7.maxVersion)) { + return true; + } + return false; + } + + compareVersion(h7, i7) { + if (!h7 || !i7) { + return false; + } + let j7 = h7.split('.').map(p7 => parseInt(p7)); + let k7 = i7.split('.').map(o7 => parseInt(o7)); + for (let n7 = 0; n7 < j7.length && n7 < k7.length; n7++) { + if (j7[n7] < k7[n7]) { + return true; + } else if (j7[n7] > k7[n7]) { + return false; + } + } + if (j7.length < k7.length) { + return true; + } + if (j7.length > k7.length) { + return false; + } + return true; + } + + getUri(g7) { + if (!g7 || g7.startsWith('file://')) { + return g7; + } + return fileUri.getUriFromPath(g7); + } + + async checkUploadFile(w6) { + if (!w6.files || w6.files.length <= 0) { + this.errorWithCodeAndMsg(UPLOAD_IMAGE_FILES_REQUIRED_ERROR, w6); + return new CheckUploadFileResult(false); + } + let x6 = new Map(); + for (let y6 = 0; y6 < w6.files?.length; y6++) { + let z6 = w6.files[y6]; + if (!z6.uri) { + this.errorWithCodeAndMsg(UPLOAD_IMAGE_FILES_URI_REQUIRED_ERROR, w6); + return new CheckUploadFileResult(false); + } + if (!z6.uri.startsWith('file://') && !fs.accessSync(z6.uri, fs.AccessModeType.EXIST)) { + this.errorWithCodeAndMsg(new Error(UPLOAD_IMAGE_FILE_NOT_EXIST_ERROR_CODE, `File uri ${z6.uri} is not exist.`), w6); + return new CheckUploadFileResult(false); + } + let a7 = z6.uri; + let b7 = z6.uri; + if (b7.indexOf(UPLOAD_IMAGE_CACHE_DIR) < 0) { + let c7 = true; + let d7 = b7.startsWith('file://') ? b7 : fileUri.getUriFromPath(z6.uri); + b7 = this.context.cacheDir + '/' + b7.substring(b7.lastIndexOf('/') + 1); + await fs.copy(d7, fileUri.getUriFromPath(b7)).catch((f7) => { + this.error(f7, w6); + c7 = false; + }); + if (!c7) { + this.errorWithCodeAndMsg(UPLOAD_FILE_ERROR, w6); + return new CheckUploadFileResult(false); + } + } + z6.uri = 'internal://' + b7.substring(b7.indexOf(UPLOAD_IMAGE_CACHE_DIR) + 1); + x6.set(b7, a7); + } + return new CheckUploadFileResult(true, x6); + } + + convertToRequestData(s6) { + let t6 = []; + if (s6) { + s6.forEach(v6 => { + if (!v6.name || !v6.value) { + return; + } + t6.push({ name: v6.name, value: v6.value }); + }); + } + return t6; + } + + convertToFile(o6) { + let p6 = []; + if (o6) { + o6.forEach(r6 => { + p6.push({ + filename: r6.filename, + name: r6.name, + uri: r6.uri, + type: r6.type + }); + }); + } + return p6; + } + + handleUploadFileResult(h6, i6, j6) { + let k6 = []; + if (h6) { + h6.forEach(m6 => { + let n6 = m6.path ? i6.get(m6.path) : m6.path; + k6.push(new UploadFileTaskState(n6 ? n6 : m6.path, m6.responseCode, m6.message)); + }); + } + this.success(new UploadFileResult(k6), j6); + } + + parseFileNameFromUrl(e6) { + if (!e6) { + return ''; + } + let f6 = e6.split('?')[0]; + if (f6.indexOf('/') < 0) { + return ''; + } + let g6 = f6.lastIndexOf('/'); + if (g6 == (f6.length - 1)) { + return ''; + } + return f6.substring(g6 + 1); + } + + saveDownloadFile(r5, s5, t5, u5) { + let v5 = new filePicker.DocumentViewPicker(); + v5.save({ + newFileNames: [s5] + }).then(z5 => { + let a6 = z5[0]; + fs.copy(fileUri.getUriFromPath(r5), a6).then(() => { + u5 && u5(a6); + }).catch((d6) => { + this.error(d6, t5); + }); + }).catch((y5) => { + this.error(y5, t5); + }); + } + + checkAccessToken(n5) { + let o5 = bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION); + let p5 = o5.appInfo.accessTokenId; + let q5 = abilityAccessCtrl.createAtManager(); + return q5.checkAccessToken(p5, n5); + } + + checkPermissions(b5, c5) { + this.checkAccessToken(b5).then(g5 => { + if (g5 == abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) { + c5(undefined); + } else { + let h5 = abilityAccessCtrl.createAtManager(); + h5.requestPermissionsFromUser(this.context, [b5]).then(l5 => { + for (let m5 = 0; m5 < l5.authResults.length; m5++) { + if (l5.authResults[m5] != 0) { + return; + } + } + c5(undefined); + }).catch((k5) => { + c5(k5); + }); + } + }).catch((f5) => { + c5(f5); + }); + } +} + +class AtomicServiceApi extends AtomicService { + constructor(y4, z4, a5) { + super(y4, z4, a5); + } + + pushUrl(u4) { + if (!this.checkRouterMode(u4.mode, u4)) { + return; + } + router.pushUrl({ url: u4.url, params: u4.params }, this.parseRouterMode(u4.mode)).then(() => { + this.success(new PushUrlResult(), u4); + }).catch((x4) => { + this.error(x4, u4); + }); + } + + replaceUrl(q4) { + if (!this.checkRouterMode(q4.mode, q4)) { + return; + } + router.replaceUrl({ url: q4.url, params: q4.params }, this.parseRouterMode(q4.mode)).then(() => { + this.success(new ReplaceUrlResult(), q4); + }).catch((t4) => { + this.error(t4, q4); + }); + } + + backUrl(p4) { + if (p4.url) { + if (!this.checkBackUrlExists(p4.url, p4)) { + return; + } + router.back({ url: p4.url, params: p4.params }); + this.success(new BackUrlResult(), p4); + } else if (p4.index || p4.index === 0) { + if (!this.checkNumberParamPositive('index', p4.index, p4)) { + return; + } + router.back(p4.index, p4.params); + this.success(new BackUrlResult(), p4); + } else if (p4.delta || p4.delta === 0) { + if (!this.checkNumberParamPositive('delta', p4.delta, p4)) { + return; + } + router.back(this.getRouterIndexByDelta(p4.delta), p4.params); + this.success(new BackUrlResult(), p4); + } else { + router.back(); + this.success(new BackUrlResult(), p4); + } + } + + clearUrl(o4) { + router.clear(); + this.success(new ClearUrlResult(), o4); + } + + pushPath(m4) { + if (!this.checkNavPathStack('navPathStack.pushPath', m4)) { + return; + } + this.navPathStack?.pushPath({ + name: m4.name, + param: m4.param, + onPop: n4 => this.onPopHandler(n4, m4.onPop) + }, m4.animated); + this.success(new PushPathResult(), m4); + } + + replacePath(k4) { + if (!this.checkNavPathStack('navPathStack.replacePath', k4)) { + return; + } + this.navPathStack?.replacePath({ + name: k4.name, + param: k4.param, + onPop: l4 => this.onPopHandler(l4, k4.onPop) + }, k4.animated); + this.success(new ReplacePathResult(), k4); + } + + popPath(h4) { + if (!this.checkNavPathStack('navPathStack.pop', h4)) { + return; + } + if (h4.name) { + let j4 = this.navPathStack?.popToName(h4.name, h4.result, h4.animated); + if (j4 === undefined || j4 === -1) { + this.errorWithCodeAndMsg(POP_PATH_NAME_NOT_EXIST_ERROR, h4); + return; + } + } else if (h4.index || h4.index === 0) { + if (h4.index < -1) { + this.errorWithCodeAndMsg(POP_PATH_PARAM_INDEX_INVALID_ERROR, h4); + return; + } + if (h4.index > this.getCurrentNavPathInfo().index) { + this.errorWithCodeAndMsg(POP_PATH_INDEX_OUT_OF_RANGE_ERROR, h4); + return; + } + this.navPathStack?.popToIndex(h4.index, h4.result, h4.animated); + } else if (h4.delta || h4.delta === 0) { + if (!this.checkNumberParamPositive('delta', h4.delta, h4)) { + return; + } + this.navPathStack?.popToIndex(this.getNavPathIndexByDelta(h4.delta), h4.result, h4.animated); + } else { + this.navPathStack?.pop(h4.result, h4.animated); + } + let i4 = this.getCurrentNavPathInfo(); + this.success(new PopPathResult(i4.name, i4.index, i4.param), h4); + } + + clearPath(g4) { + if (!this.checkNavPathStack('navPathStack.clear', g4)) { + return; + } + this.navPathStack?.clear(g4.animated); + this.success(new ClearPathResult(), g4); + } + + postMessage(c3) { + c3.data && this.messageDataList.push(c3.data); + this.success(new PostMessageResult(), c3); + } + + getEnv(e4) { + let f4 = new GetEnvResult(); + f4.deviceType = deviceInfo.deviceType; + f4.brand = deviceInfo.brand; + f4.productModel = deviceInfo.productModel; + f4.osFullName = deviceInfo.osFullName; + this.success(f4, e4); + } + + checkJsApi(a4) { + let b4 = new Map(); + a4.jsApiList?.forEach(d4 => { + b4[d4] = this.isJsApiEnable(ATOMIC_SERVICE_JS_API_MAP.get(d4)); + }); + this.success(new CheckJsApiResult(b4), a4); + } + + pickCamera(v3) { + picker.pick(this.context, v3.mediaTypes, { + cameraPosition: v3.cameraPosition, + saveUri: v3.saveUri, + videoDuration: v3.videoDuration + }).then((z3) => { + this.success(new PickCameraResult(z3.resultCode, z3.resultUri, z3.mediaType), v3); + }).catch((y3) => { + this.error(y3, v3); + }); + } + + selectPhoto(p3) { + let q3 = new photoAccessHelper.PhotoViewPicker(); + q3.select({ + MIMEType: p3.mimeType, + maxSelectNumber: p3.maxSelectNumber, + isPhotoTakingSupported: p3.isPhotoTakingSupported, + isEditSupported: p3.isEditSupported, + isSearchSupported: p3.isSearchSupported, + recommendationOptions: { + recommendationType: p3.recommendationType + }, + preselectedUris: p3.preselectedUris + }).then((u3) => { + this.success(new SelectPhotoResult(u3.photoUris, u3.isOriginalPhoto), p3); + }).catch((t3) => { + this.error(t3, p3); + }); + } + + openPreview(g3) { + let h3 = this.getUri(g3.uri); + filePreview.canPreview(this.context, h3).then((l3) => { + if (!l3) { + this.errorWithCodeAndMsg(IMAGE_CAN_NOT_PREVIEW_ERROR, g3); + return; + } + filePreview.openPreview(this.context, { + uri: h3, + mimeType: g3.mimeType, + title: g3.title + }).then(() => { + this.success(new OpenPreviewResult(), g3); + }).catch((o3) => { + this.error(o3, g3); + }); + }).catch((k3) => { + this.error(k3, g3); + }); + } + + uploadFile(s2) { + this.checkUploadFile(s2).then(w2 => { + if (!w2.checkResult) { + return; + } + let x2 = { + url: s2.url, + header: s2.header, + method: s2.method, + files: this.convertToFile(s2.files), + data: this.convertToRequestData(s2.data) + }; + this.consoleLog('uploadFile uploadConfig=' + JSON.stringify(x2)); + request.uploadFile(this.context, x2).then((b3) => { + b3.on('complete', (f3) => { + this.handleUploadFileResult(f3, w2.uriMap, s2); + }); + b3.on('fail', (e3) => { + this.handleUploadFileResult(e3, w2.uriMap, s2); + }); + }).catch((a3) => { + this.error(a3, s2); + }); + }).catch((v2) => { + this.error(v2, s2); + }); + } + + downloadFile(f2) { + let g2 = f2.fileName ? f2.fileName : this.parseFileNameFromUrl(f2.url); + let h2 = `${util.generateRandomUUID().replaceAll('-', '')}`; + let i2 = `${this.context.cacheDir}/${h2}`; + request.downloadFile(this.context, { + url: f2.url, + header: f2.header ? f2.header : new Object(), + filePath: i2, + enableMetered: f2.enableMetered, + enableRoaming: f2.enableRoaming, + networkType: f2.networkType, + background: false + }).then((m2) => { + m2.on('complete', () => { + this.saveDownloadFile(i2, g2, f2, r2 => { + this.success(new DownloadFileResult(r2), f2); + }); + }); + m2.on('fail', y2 => { + this.errorWithCodeAndMsg(new Error(y2, 'File download fail.'), f2); + }); + }).catch((l2) => { + this.error(l2, f2); + }); + } + + getNetworkType(v1) { + connection.getDefaultNet().then(z1 => { + if (!z1 || z1.netId === 0) { + this.errorWithCodeAndMsg(NETWORK_NO_ACTIVE_ERROR, v1); + return; + } + connection.getNetCapabilities(z1).then(n2 => { + let t2 = new GetNetworkTypeResult(n2.bearerTypes, n2.networkCap, n2.linkUpBandwidthKbps, n2.linkDownBandwidthKbps); + this.success(t2, v1); + }).catch((j2) => { + this.error(j2, v1); + }); + }).catch((y1) => { + this.error(y1, v1); + }); + } + + getLocation(n1) { + this.checkPermissions(PERMISSION_APPROXIMATELY_LOCATION, p1 => { + if (p1) { + this.error(p1, n1); + return; + } + geoLocationManager.getCurrentLocation({ + priority: n1.priority, + scenario: n1.scenario, + maxAccuracy: n1.maxAccuracy, + timeoutMs: n1.timeoutMs + }).then(t1 => { + let u1 = new GetLocationResult(t1.latitude, t1.longitude, t1.altitude, t1.accuracy, t1.speed, t1.timeStamp, t1.direction, t1.timeSinceBoot, + t1.additions, t1.additionSize); + this.success(u1, n1); + }).catch((s1) => { + this.error(s1, n1); + }); + }); + } +} + +class NavPathInfo { + constructor(l1, m1) { + this.name = l1; + this.index = m1; + } +} + +class CheckUploadFileResult { + constructor(j1, k1) { + this.checkResult = j1; + this.uriMap = k1; + } +} + +class BaseOptions { +} + +class PushUrlOptions extends BaseOptions { +} + +class PushUrlResult { +} + +class ReplaceUrlOptions extends BaseOptions { +} + +class ReplaceUrlResult { +} + +class BackUrlOptions extends BaseOptions { +} + +class BackUrlResult { +} + +class ClearUrlOptions extends BaseOptions { +} + +class ClearUrlResult { +} + +class OnPopEvent { + constructor(g1, h1, i1) { + this.name = g1; + this.param = h1; + this.result = i1; + } +} + +class PushPathOptions extends BaseOptions { +} + +class PushPathResult { +} + +class ReplacePathOptions extends BaseOptions { +} + +class ReplacePathResult { +} + +class PopPathOptions extends BaseOptions { +} + +class PopPathResult { + constructor(d1, e1, f1) { + this.name = d1; + this.index = e1; + this.param = f1; + } +} + +class ClearPathOptions extends BaseOptions { +} + +class ClearPathResult { +} + +class PostMessageOptions extends BaseOptions { +} + +class PostMessageResult { +} + +export class OnMessageEvent { +} + +class GetEnvOptions extends BaseOptions { +} + +class GetEnvResult { +} + +class CheckJsApiOptions extends BaseOptions { +} + +class CheckJsApiResult { + constructor(c1) { + this.checkResult = c1; + } +} + +class PickCameraOptions extends BaseOptions { +} + +class PickCameraResult { + constructor(z, a1, b1) { + this.resultCode = z; + this.resultUri = a1; + this.mediaType = b1; + } +} + +class SelectPhotoOptions extends BaseOptions { +} + +class SelectPhotoResult { + constructor(x, y) { + this.photoUris = x; + this.isOriginalPhoto = y; + } +} + +class OpenPreviewOptions extends BaseOptions { +} + +class OpenPreviewResult { +} + +class UploadFileOptions extends BaseOptions { +} + +class UploadFile { + constructor(t, u, v, w) { + this.filename = t; + this.name = u; + this.uri = v; + this.type = w; + } +} + +class UploadRequestData { +} + +class UploadFileResult { + constructor(s) { + this.taskStates = s; + } +} + +class UploadFileTaskState { + constructor(p, q, r) { + this.path = p; + this.responseCode = q; + this.message = r; + } +} + +class DownloadFileOptions extends BaseOptions { +} + +class DownloadFileResult { + constructor(o) { + this.uri = o; + } +} + +class GetNetworkTypeOptions extends BaseOptions { +} + +class GetNetworkTypeResult { + constructor(k, l, m, n) { + this.bearerTypes = k; + this.networkCap = l; + this.linkUpBandwidthKbps = m; + this.linkDownBandwidthKbps = n; + } +} + +class GetLocationOptions extends BaseOptions { +} + +class GetLocationResult { + constructor(a, b, c, d, e, f, g, h, i, j) { + this.latitude = a; + this.longitude = b; + this.altitude = c; + this.accuracy = d; + this.speed = e; + this.timeStamp = f; + this.direction = g; + this.timeSinceBoot = h; + this.additions = i; + this.additionSize = j; + } +} + +export default { + AtomicServiceWeb +} diff --git a/advanced_ui_component/atomicserviceweb/interfaces/include/api_policy_adapter.h b/advanced_ui_component/atomicserviceweb/interfaces/include/api_policy_adapter.h new file mode 100644 index 00000000000..1813da19a3b --- /dev/null +++ b/advanced_ui_component/atomicserviceweb/interfaces/include/api_policy_adapter.h @@ -0,0 +1,27 @@ +/* + * 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. + */ + +#include "string" + +class ApiPolicyAdapter { +public: + ApiPolicyAdapter(); + ~ApiPolicyAdapter(); + + int32_t CheckUrl(std::string bundleName, std::string domainType, std::string url); + +private: + void *handle = nullptr; +}; diff --git a/advanced_ui_component/atomicserviceweb/source/atomicserviceweb.ets b/advanced_ui_component/atomicserviceweb/source/atomicserviceweb.ets new file mode 100644 index 00000000000..e09e9450b13 --- /dev/null +++ b/advanced_ui_component/atomicserviceweb/source/atomicserviceweb.ets @@ -0,0 +1,1146 @@ +/* + * 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. + */ + +import web_webview from '@ohos.web.webview'; +import router from '@ohos.router'; +import deviceInfo from '@ohos.deviceInfo'; +import common from '@ohos.app.ability.common'; +import geoLocationManager from '@ohos.geoLocationManager'; +import bundleManager from '@ohos.bundle.bundleManager'; +import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl'; +import connection from '@ohos.net.connection'; +import request from '@ohos.request'; +import fs from '@ohos.file.fs'; +import util from '@ohos.util'; +import photoAccessHelper from '@ohos.file.photoAccessHelper'; +import { filePreview } from '@kit.PreviewKit'; +import fileUri from '@ohos.file.fileuri'; +import picker from '@ohos.multimedia.cameraPicker'; +import filePicker from '@ohos.file.picker'; +import { BusinessError } from '@ohos.base'; + +class Error { + code: number; + message: string; + + constructor(code: number, message: string) { + this.code = code; + this.message = message; + } +} + +class JsApiConfig { + apiName: string; + minVersion: string; + maxVersion: string; + requiredFieldNames?: string[]; + + constructor(apiName: string, minVersion: string, maxVersion: string, requiredFieldNames?: string[]) { + this.apiName = apiName; + this.minVersion = minVersion; + this.maxVersion = maxVersion; + this.requiredFieldNames = requiredFieldNames; + } +} + +const LOG_ENABLE: boolean = true; +const LOG_PREFIX: string = '[AtomicServiceWebLog]'; +const UPLOAD_IMAGE_CACHE_DIR: string = '/cache/'; +const JAVA_SCRIPT_PROXY_OBJECT_NAME: string = 'atomicServiceProxy'; +const JAVA_SCRIPT_PROXY_API_NAME_LIST: string[] = ['invokeJsApi']; +const ATOMIC_SERVICE_JS_API_MAP = new Map(); +const registerJsApi = (apiNameAlias: string, apiName: string, minVersion: string, maxVersion: string, requiredFieldNames: string[]): void => { + ATOMIC_SERVICE_JS_API_MAP.set(apiNameAlias, new JsApiConfig(apiName, minVersion, maxVersion, requiredFieldNames)); +}; +const MAX_VERSION = '99.99.99'; +const ATOMIC_SERVICE_JS_SDK_CURRENT_VERSION = '1.0.0'; +const PERMISSION_APPROXIMATELY_LOCATION: Permissions = 'ohos.permission.APPROXIMATELY_LOCATION'; + +const SYSTEM_INTERNAL_ERROR: Error = new Error(500, 'System internal error.'); +const JS_API_INVALID_INVOKE_ERROR: Error = new Error(200001, 'Invalid invoke.'); +const PARAM_REQUIRED_ERROR_CODE: number = 200002; +const PARAM_NUMBER_POSITIVE_ERROR_CODE: number = 200003; +const ROUTER_PARAM_MODE_INVALID_ERROR: Error = new Error(200004, 'Param mode is invalid.'); +const BACK_URL_NOT_EXIST_OR_OPENED_ERROR: Error = new Error(200005, 'Url is not exist or opened, can not be back.'); +const NAV_PATH_STACK_NOT_EXIST_ERROR_CODE: number = 200006; +const POP_PATH_NAME_NOT_EXIST_ERROR: Error = new Error(200007, 'Name is not exist or opened, can not be pop.'); +const POP_PATH_PARAM_INDEX_INVALID_ERROR: Error = new Error(200008, 'Param index is invalid.'); +const POP_PATH_INDEX_OUT_OF_RANGE_ERROR: Error = new Error(200009, 'The Index is out of range.'); +const UPLOAD_IMAGE_FILES_REQUIRED_ERROR: Error = new Error(200010, 'Param files is required.'); +const UPLOAD_IMAGE_FILE_NOT_EXIST_ERROR_CODE: number = 200011; +const UPLOAD_IMAGE_FILES_URI_REQUIRED_ERROR: Error = new Error(200012, 'Param uri of files is required.'); +const UPLOAD_FILE_ERROR: Error = new Error(200013, 'Upload file error.'); +const IMAGE_CAN_NOT_PREVIEW_ERROR: Error = new Error(200014, 'The filePath can not preview.'); +const NETWORK_NO_ACTIVE_ERROR: Error = new Error(200015, 'The network is not active.'); + +{ + registerJsApi('router.pushUrl', 'pushUrl', '1.0.0', MAX_VERSION, ['url']); + registerJsApi('router.replaceUrl', 'replaceUrl', '1.0.0', MAX_VERSION, ['url']); + registerJsApi('router.back', 'backUrl', '1.0.0', MAX_VERSION, []); + registerJsApi('router.clear', 'clearUrl', '1.0.0', MAX_VERSION, []); + registerJsApi('navPathStack.pushPath', 'pushPath', '1.0.0', MAX_VERSION, ['name']); + registerJsApi('navPathStack.replacePath', 'replacePath', '1.0.0', MAX_VERSION, ['name']); + registerJsApi('navPathStack.pop', 'popPath', '1.0.0', MAX_VERSION, []); + registerJsApi('navPathStack.clear', 'clearPath', '1.0.0', MAX_VERSION, []); + registerJsApi('asWeb.postMessage', 'postMessage', '1.0.0', MAX_VERSION, ['data']); + registerJsApi('asWeb.getEnv', 'getEnv', '1.0.0', MAX_VERSION, []); + registerJsApi('asWeb.checkJsApi', 'checkJsApi', '1.0.0', MAX_VERSION, ['jsApiList']); + registerJsApi('cameraPicker.pick', 'pickCamera', '1.0.0', MAX_VERSION, ['mediaTypes', 'cameraPosition']); + registerJsApi('photoViewPicker.select', 'selectPhoto', '1.0.0', MAX_VERSION, []); + registerJsApi('filePreview.openPreview', 'openPreview', '1.0.0', MAX_VERSION, ['uri']); + registerJsApi('request.uploadFile', 'uploadFile', '1.0.0', MAX_VERSION, ['url', 'files']); + registerJsApi('request.downloadFile', 'downloadFile', '1.0.0', MAX_VERSION, ['url']); + registerJsApi('connection.getNetworkType', 'getNetworkType', '1.0.0', MAX_VERSION, []); + registerJsApi('location.getLocation', 'getLocation', '1.0.0', MAX_VERSION, []); +} + +@Component +export struct AtomicServiceWeb { + @Prop src: ResourceStr; + navPathStack?: NavPathStack; + onMessage?: (event?: OnMessageEvent) => void = () => { + }; + private context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext; + private controller: web_webview.WebviewController = new web_webview.WebviewController(); + private schemeHandler: web_webview.WebSchemeHandler = new web_webview.WebSchemeHandler(); + private atomicService?: AtomicService; + private atomicServiceProxy?: AtomicServiceProxy; + + aboutToAppear(): void { + if (!this.atomicService) { + this.atomicService = new AtomicServiceApi(this.context, this.navPathStack, this.onMessage); + this.atomicServiceProxy = new AtomicServiceProxy(this.atomicService); + } + } + + aboutToDisappear(): void { + this.atomicService?.notifyMessage(); + } + + build() { + Web({ src: this.src, controller: this.controller }) + .fileAccess(true) + .imageAccess(true) + .onlineImageAccess(true) + .javaScriptAccess(true) + .domStorageAccess(true) + .geolocationAccess(true) + .onControllerAttached(() => { + this.registerJavaScriptProxy(); + this.schemeHandler.onRequestStart((request: web_webview.WebSchemeHandlerRequest) => { + return !this.checkUrl(request.getRequestUrl()); + }); + this.controller.setWebSchemeHandler('https', this.schemeHandler); + }) + .onOverrideUrlLoading((webResourceRequest: WebResourceRequest) => { + return !this.checkUrl(webResourceRequest.getRequestUrl()); + }) + .onLoadIntercept(event => { + return !this.checkUrl(event.data.getRequestUrl()); + }) + } + + registerJavaScriptProxy(): void { + try { + this.controller.registerJavaScriptProxy(this.atomicServiceProxy, JAVA_SCRIPT_PROXY_OBJECT_NAME, JAVA_SCRIPT_PROXY_API_NAME_LIST); + } catch (error) { + let e: BusinessError = error as BusinessError; + console.error(`AtomicServiceWeb registerJavaScriptProxy failed, code is ${e.code}, message is ${e.message}`); + } + } + + cutUrl(url: string): string { + if (url) { + let index: number = url.indexOf('?'); + if (index > -1) { + return url.substring(0, index); + } + } + return url; + } + + checkUrl(url: string): boolean { + if (!url) { + return false; + } + if (url.startsWith('resource://rawfile')) { + return true; + } + url = this.cutUrl(url); + console.log(`AtomicServiceWebLog checkUrl url=${url}`); + return true; + } +} + +class AtomicServiceProxy { + private atomicService: AtomicService; + + constructor(atomicService: AtomicService) { + this.atomicService = atomicService; + } + + invokeJsApi(apiNameAlias: string, options: BaseOptions): void { + try { + options = options || {}; + if (!apiNameAlias || !ATOMIC_SERVICE_JS_API_MAP.has(apiNameAlias)) { + this.atomicService.errorWithCodeAndMsg(JS_API_INVALID_INVOKE_ERROR, options); + return; + } + this.atomicService.logOptions(apiNameAlias, options); + let jsApiConfig: JsApiConfig | undefined = ATOMIC_SERVICE_JS_API_MAP.get(apiNameAlias); + if (!this.atomicService.checkRequiredFieldInOptions(jsApiConfig, options)) { + return; + } + let atomicService: object = this.atomicService; + atomicService[jsApiConfig?.apiName as string](options); + } catch (err) { + this.atomicService.error(err, options); + } + } +} + +class AtomicService { + context: common.UIAbilityContext; + navPathStack?: NavPathStack; + messageDataList: object[] = []; + onMessage: (event?: OnMessageEvent) => void = () => { + }; + + constructor(context: common.UIAbilityContext, navPathStack?: NavPathStack, onMessage?: (event?: OnMessageEvent) => void) { + this.context = context; + this.navPathStack = navPathStack; + this.onMessage = onMessage ? onMessage : this.onMessage; + } + + success(res: T, options: BaseOptions): void { + options?.callback && options?.callback(undefined, res); + } + + error(err: BusinessError, options: BaseOptions,): void { + options?.callback && options?.callback(new Error(err.code ? err.code : SYSTEM_INTERNAL_ERROR.code, + err.message ? err.message : SYSTEM_INTERNAL_ERROR.message)); + } + + errorWithCodeAndMsg(error: Error, options: BaseOptions): void { + options?.callback && options?.callback(error); + } + + consoleLog(msg: string): void { + if (LOG_ENABLE) { + console.log(`${LOG_PREFIX} ${msg}`); + } + } + + consoleError(msg: string): void { + if (LOG_ENABLE) { + console.error(`${LOG_PREFIX} ${msg}`); + } + } + + logOptions(name: string, options: BaseOptions): void { + this.consoleLog(`${name} options=${JSON.stringify(options)}`); + } + + checkParamRequired(paramKey: string, paramValue: V, options: BaseOptions): boolean { + if (paramValue === undefined || paramValue === null || paramValue === '') { + this.errorWithCodeAndMsg(new Error(PARAM_REQUIRED_ERROR_CODE, `Param ${paramKey} is required.`), options); + return false; + } + return true; + } + + checkNumberParamPositive(paramKey: string, paramValue: number, options: BaseOptions): boolean { + if (paramValue <= 0) { + this.errorWithCodeAndMsg(new Error(PARAM_NUMBER_POSITIVE_ERROR_CODE, `Param ${paramKey} must be a positive number.`), options); + return false; + } + return true; + } + + checkRequiredFieldInOptions(jsApiConfig: JsApiConfig | undefined, options: BaseOptions): boolean { + if (!jsApiConfig) { + return false; + } + if (!jsApiConfig.requiredFieldNames) { + return true; + } + let obj: object = options; + for (let i = 0; i < jsApiConfig.requiredFieldNames.length; i++) { + let fieldName: string = jsApiConfig.requiredFieldNames[i]; + if (!this.checkParamRequired(fieldName, obj[fieldName], options)) { + return false; + } + } + return true; + } + + checkRouterMode(mode: string | undefined, options: BaseOptions): boolean { + if (!mode || mode === 'Single' || mode === 'Standard') { + return true; + } + this.errorWithCodeAndMsg(ROUTER_PARAM_MODE_INVALID_ERROR, options); + return false; + } + + parseRouterMode(routerMode?: string): router.RouterMode { + return routerMode === 'Single' ? router.RouterMode.Single : router.RouterMode.Standard; + } + + getRouterIndexByDelta(delta: number): number { + let length: number = parseInt(router.getLength()); + for (let i = length; i > 0; i--) { + let state = router.getStateByIndex(i); + if (state?.name && delta-- == 0) { + return i; + } + } + return 1; + } + + checkBackUrlExists(url: string, options: BaseOptions): boolean { + let length: number = parseInt(router.getLength()); + for (let i = length; i > 0; i--) { + let state = router.getStateByIndex(i); + if (state?.name) { + let stateUrl: string = state?.path + state?.name; + if (stateUrl === url) { + return true; + } + } + } + this.errorWithCodeAndMsg(BACK_URL_NOT_EXIST_OR_OPENED_ERROR, options); + return false; + } + + checkNavPathStack(apiName: string, options: BaseOptions): boolean { + if (!this.navPathStack) { + this.errorWithCodeAndMsg(new Error(NAV_PATH_STACK_NOT_EXIST_ERROR_CODE, `Current page is not NavDestination, not support ${apiName}().`), options); + return false; + } + return true; + } + + getNavPathIndexByDelta(delta: number): number { + let pathStack: string[] | undefined = this.navPathStack?.getAllPathName(); + if (!pathStack || pathStack.length == 0) { + return -1; + } + return pathStack.length > delta ? (pathStack.length - delta - 1) : -1; + } + + onPopHandler(popInfo: PopInfo, onPop?: (event: OnPopEvent) => void): void { + if (!popInfo?.info || !onPop) { + return; + } + onPop(new OnPopEvent(popInfo.info.name, popInfo.info.param as object, popInfo.result)); + } + + getCurrentNavPathInfo(): NavPathInfo { + let navPathStack: Array | undefined = this.navPathStack?.getAllPathName(); + let navPathInfo: NavPathInfo = (navPathStack && navPathStack.length > 0) ? new NavPathInfo(navPathStack[navPathStack.length - 1], navPathStack.length - 1) : + new NavPathInfo(undefined, -1); + if (navPathInfo.index >= 0) { + navPathInfo.param = this.navPathStack?.getParamByIndex(navPathInfo.index) as object; + } + return navPathInfo; + } + + notifyMessage(): void { + if (this.messageDataList.length <= 0) { + return; + } + this.onMessage({ data: this.messageDataList }); + this.messageDataList = []; + } + + isJsApiEnable(jsApiConfig?: JsApiConfig): boolean { + if (!jsApiConfig) { + return false; + } + if (this.compareVersion(jsApiConfig.minVersion, ATOMIC_SERVICE_JS_SDK_CURRENT_VERSION) && + this.compareVersion(ATOMIC_SERVICE_JS_SDK_CURRENT_VERSION, jsApiConfig.maxVersion)) { + return true; + } + return false; + } + + compareVersion(lowVersion: string, highVersion: string): boolean { + if (!lowVersion || !highVersion) { + return false; + } + let v1 = lowVersion.split('.').map(m => parseInt(m)); + let v2 = highVersion.split('.').map(m => parseInt(m)); + for (let i = 0; i < v1.length && i < v2.length; i++) { + if (v1[i] < v2[i]) { + return true; + } else if (v1[i] > v2[i]) { + return false; + } + } + if (v1.length < v2.length) { + return true; + } + if (v1.length > v2.length) { + return false; + } + return true; + } + + getUri(uriOrFilePath: string): string { + if (!uriOrFilePath || uriOrFilePath.startsWith('file://')) { + return uriOrFilePath; + } + return fileUri.getUriFromPath(uriOrFilePath); + } + + async checkUploadFile(options: UploadFileOptions): Promise { + if (!options.files || options.files.length <= 0) { + this.errorWithCodeAndMsg(UPLOAD_IMAGE_FILES_REQUIRED_ERROR, options); + return new CheckUploadFileResult(false); + } + let uriMap: Map = new Map(); + for (let i = 0; i < options.files?.length; i++) { + let file: UploadFile = options.files[i]; + if (!file.uri) { + this.errorWithCodeAndMsg(UPLOAD_IMAGE_FILES_URI_REQUIRED_ERROR, options); + return new CheckUploadFileResult(false); + } + if (!file.uri.startsWith('file://') && !fs.accessSync(file.uri, fs.AccessModeType.EXIST)) { + this.errorWithCodeAndMsg(new Error(UPLOAD_IMAGE_FILE_NOT_EXIST_ERROR_CODE, `File uri ${file.uri} is not exist.`), options); + return new CheckUploadFileResult(false); + } + let originUri: string = file.uri; + let uploadUri: string = file.uri; + if (uploadUri.indexOf(UPLOAD_IMAGE_CACHE_DIR) < 0) { + let res: boolean = true; + let srcUri: string = uploadUri.startsWith('file://') ? uploadUri : fileUri.getUriFromPath(file.uri); + uploadUri = this.context.cacheDir + '/' + uploadUri.substring(uploadUri.lastIndexOf('/') + 1); + await fs.copy(srcUri, fileUri.getUriFromPath(uploadUri)).catch((err: BusinessError) => { + this.error(err, options); + res = false; + }); + if (!res) { + this.errorWithCodeAndMsg(UPLOAD_FILE_ERROR, options); + return new CheckUploadFileResult(false); + } + } + file.uri = 'internal://' + uploadUri.substring(uploadUri.indexOf(UPLOAD_IMAGE_CACHE_DIR) + 1); + uriMap.set(uploadUri, originUri); + } + return new CheckUploadFileResult(true, uriMap); + } + + convertToRequestData(data?: UploadRequestData[]): request.RequestData[] { + let requestData: request.RequestData[] = []; + if (data) { + data.forEach(item => { + if (!item.name || !item.value) { + return; + } + requestData.push({ name: item.name, value: item.value }); + }); + } + return requestData; + } + + convertToFile(files?: UploadFile[]): request.File[] { + let requestFiles: request.File[] = []; + if (files) { + files.forEach(item => { + requestFiles.push({ + filename: item.filename, + name: item.name, + uri: item.uri, + type: item.type + }); + }); + } + return requestFiles; + } + + handleUploadFileResult(taskStateArray: Array, uriMap: Map, options: UploadFileOptions): void { + let taskStates: UploadFileTaskState[] = []; + if (taskStateArray) { + taskStateArray.forEach(taskState => { + let path: (string | undefined) = taskState.path ? uriMap.get(taskState.path) : taskState.path; + taskStates.push(new UploadFileTaskState(path ? path : taskState.path, taskState.responseCode, taskState.message)); + }); + } + this.success(new UploadFileResult(taskStates), options); + } + + parseFileNameFromUrl(url?: string): string { + if (!url) { + return ''; + } + let http: string = url.split('?')[0]; + if (http.indexOf('/') < 0) { + return ''; + } + let index: number = http.lastIndexOf('/'); + if (index == (http.length - 1)) { + return ''; + } + return http.substring(index + 1); + } + + saveDownloadFile(filePath: string, fileName: string, options: DownloadFileOptions, callback: (uri: string) => void): void { + let documentPicker = new filePicker.DocumentViewPicker(); + documentPicker.save({ + newFileNames: [fileName] + }).then(res => { + let uri: string = res[0]; + fs.copy(fileUri.getUriFromPath(filePath), uri).then(() => { + callback && callback(uri); + }).catch((err: BusinessError) => { + this.error(err, options); + }); + }).catch((err: BusinessError) => { + this.error(err, options); + }); + } + + checkAccessToken(permissionName: Permissions): Promise { + let bundleInfo: bundleManager.BundleInfo = bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION); + let tokenId: number = bundleInfo.appInfo.accessTokenId; + let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager(); + return atManager.checkAccessToken(tokenId, permissionName); + } + + checkPermissions(permissionName: Permissions, grantCallback: (err?: BusinessError) => void): void { + this.checkAccessToken(permissionName).then(grantStatus => { + if (grantStatus == abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) { + grantCallback(undefined); + } else { + let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager(); + atManager.requestPermissionsFromUser(this.context, [permissionName]).then(permissionRequestResult => { + for (let i = 0; i < permissionRequestResult.authResults.length; i++) { + if (permissionRequestResult.authResults[i] != 0) { + return; + } + } + grantCallback(undefined); + }).catch((err: BusinessError) => { + grantCallback(err); + }); + } + }).catch((err: BusinessError) => { + grantCallback(err); + }); + } +} + +class AtomicServiceApi extends AtomicService { + constructor(context: common.UIAbilityContext, navPathStack?: NavPathStack, onMessage?: (event?: OnMessageEvent) => void) { + super(context, navPathStack, onMessage); + } + + pushUrl(options: PushUrlOptions): void { + if (!this.checkRouterMode(options.mode, options)) { + return; + } + router.pushUrl({ url: options.url, params: options.params }, this.parseRouterMode(options.mode)).then(() => { + this.success(new PushUrlResult(), options); + }).catch((err: BusinessError) => { + this.error(err, options); + }); + } + + replaceUrl(options: ReplaceUrlOptions): void { + if (!this.checkRouterMode(options.mode, options)) { + return; + } + router.replaceUrl({ url: options.url, params: options.params }, this.parseRouterMode(options.mode)).then(() => { + this.success(new ReplaceUrlResult(), options); + }).catch((err: BusinessError) => { + this.error(err, options); + }); + } + + backUrl(options: BackUrlOptions): void { + if (options.url) { + if (!this.checkBackUrlExists(options.url, options)) { + return; + } + router.back({ url: options.url, params: options.params }); + this.success(new BackUrlResult(), options); + } else if (options.index || options.index === 0) { + if (!this.checkNumberParamPositive('index', options.index, options)) { + return; + } + router.back(options.index, options.params); + this.success(new BackUrlResult(), options); + } else if (options.delta || options.delta === 0) { + if (!this.checkNumberParamPositive('delta', options.delta, options)) { + return; + } + router.back(this.getRouterIndexByDelta(options.delta), options.params); + this.success(new BackUrlResult(), options); + } else { + router.back(); + this.success(new BackUrlResult(), options); + } + } + + clearUrl(options: ClearUrlOptions): void { + router.clear(); + this.success(new ClearUrlResult(), options); + } + + pushPath(options: PushPathOptions): void { + if (!this.checkNavPathStack('navPathStack.pushPath', options)) { + return; + } + this.navPathStack?.pushPath({ + name: options.name, + param: options.param, + onPop: popInfo => this.onPopHandler(popInfo, options.onPop) + }, options.animated); + this.success(new PushPathResult(), options); + } + + replacePath(options: ReplacePathOptions): void { + if (!this.checkNavPathStack('navPathStack.replacePath', options)) { + return; + } + this.navPathStack?.replacePath({ + name: options.name, + param: options.param, + onPop: popInfo => this.onPopHandler(popInfo, options.onPop) + }, options.animated); + this.success(new ReplacePathResult(), options); + } + + popPath(options: PopPathOptions): void { + if (!this.checkNavPathStack('navPathStack.pop', options)) { + return; + } + if (options.name) { + let index: number | undefined = this.navPathStack?.popToName(options.name, options.result, options.animated); + if (index === undefined || index === -1) { + this.errorWithCodeAndMsg(POP_PATH_NAME_NOT_EXIST_ERROR, options); + return; + } + } else if (options.index || options.index === 0) { + if (options.index < -1) { + this.errorWithCodeAndMsg(POP_PATH_PARAM_INDEX_INVALID_ERROR, options); + return; + } + if (options.index > this.getCurrentNavPathInfo().index) { + this.errorWithCodeAndMsg(POP_PATH_INDEX_OUT_OF_RANGE_ERROR, options); + return; + } + this.navPathStack?.popToIndex(options.index, options.result, options.animated); + } else if (options.delta || options.delta === 0) { + if (!this.checkNumberParamPositive('delta', options.delta, options)) { + return; + } + this.navPathStack?.popToIndex(this.getNavPathIndexByDelta(options.delta), options.result, options.animated); + } else { + this.navPathStack?.pop(options.result, options.animated); + } + let navPathInfo: NavPathInfo = this.getCurrentNavPathInfo(); + this.success(new PopPathResult(navPathInfo.name, navPathInfo.index, navPathInfo.param), options); + } + + clearPath(options: ClearPathOptions): void { + if (!this.checkNavPathStack('navPathStack.clear', options)) { + return; + } + this.navPathStack?.clear(options.animated); + this.success(new ClearPathResult(), options); + } + + postMessage(options: PostMessageOptions): void { + options.data && this.messageDataList.push(options.data); + this.success(new PostMessageResult(), options); + } + + getEnv(options: GetEnvOptions): void { + let res: GetEnvResult = new GetEnvResult(); + res.deviceType = deviceInfo.deviceType; + res.brand = deviceInfo.brand; + res.productModel = deviceInfo.productModel; + res.osFullName = deviceInfo.osFullName; + this.success(res, options); + } + + checkJsApi(options: CheckJsApiOptions): void { + let res: Map = new Map(); + options.jsApiList?.forEach(jsApi => { + res[jsApi] = this.isJsApiEnable(ATOMIC_SERVICE_JS_API_MAP.get(jsApi)); + }); + this.success(new CheckJsApiResult(res), options); + } + + pickCamera(options: PickCameraOptions): void { + picker.pick(this.context, options.mediaTypes as Array, { + cameraPosition: options.cameraPosition, + saveUri: options.saveUri, + videoDuration: options.videoDuration + }).then((pickerResult: picker.PickerResult) => { + this.success(new PickCameraResult(pickerResult.resultCode, pickerResult.resultUri, pickerResult.mediaType), options); + }).catch((err: BusinessError) => { + this.error(err, options); + }); + } + + selectPhoto(options: SelectPhotoOptions): void { + let photoViewPicker = new photoAccessHelper.PhotoViewPicker(); + photoViewPicker.select({ + MIMEType: options.mimeType as photoAccessHelper.PhotoViewMIMETypes, + maxSelectNumber: options.maxSelectNumber, + isPhotoTakingSupported: options.isPhotoTakingSupported, + isEditSupported: options.isEditSupported, + isSearchSupported: options.isSearchSupported, + recommendationOptions: { + recommendationType: options.recommendationType + }, + preselectedUris: options.preselectedUris + }).then((selectResult: photoAccessHelper.PhotoSelectResult) => { + this.success(new SelectPhotoResult(selectResult.photoUris, selectResult.isOriginalPhoto), options); + }).catch((err: BusinessError) => { + this.error(err, options); + }); + } + + openPreview(options: OpenPreviewOptions): void { + let uri: string = this.getUri(options.uri as string); + filePreview.canPreview(this.context, uri).then((res: boolean) => { + if (!res) { + this.errorWithCodeAndMsg(IMAGE_CAN_NOT_PREVIEW_ERROR, options); + return; + } + filePreview.openPreview(this.context, { + uri: uri, + mimeType: options.mimeType as string, + title: options.title + }).then(() => { + this.success(new OpenPreviewResult(), options); + }).catch((err: BusinessError) => { + this.error(err, options); + }); + }).catch((err: BusinessError) => { + this.error(err, options); + }); + } + + uploadFile(options: UploadFileOptions): void { + this.checkUploadFile(options).then(res => { + if (!res.checkResult) { + return; + } + let uploadConfig: request.UploadConfig = { + url: options.url as string, + header: options.header as object, + method: options.method as string, + files: this.convertToFile(options.files), + data: this.convertToRequestData(options.data) + }; + this.consoleLog('uploadFile uploadConfig=' + JSON.stringify(uploadConfig)); + request.uploadFile(this.context, uploadConfig).then((uploadTask: request.UploadTask) => { + uploadTask.on('complete', (taskStateArray: Array) => { + this.handleUploadFileResult(taskStateArray, res.uriMap as Map, options); + }); + uploadTask.on('fail', (taskStateArray: Array) => { + this.handleUploadFileResult(taskStateArray, res.uriMap as Map, options); + }); + }).catch((err: BusinessError) => { + this.error(err, options); + }); + }).catch((err: BusinessError) => { + this.error(err, options); + }); + } + + downloadFile(options: DownloadFileOptions): void { + let fileName: string = options.fileName ? options.fileName : this.parseFileNameFromUrl(options.url); + let cacheFileName: string = `${util.generateRandomUUID().replaceAll('-', '')}`; + let filePath: string = `${this.context.cacheDir}/${cacheFileName}`; + request.downloadFile(this.context, { + url: options.url, + header: options.header ? options.header : new Object(), + filePath: filePath, + enableMetered: options.enableMetered, + enableRoaming: options.enableRoaming, + networkType: options.networkType, + background: false + }).then((downloadTask: request.DownloadTask) => { + downloadTask.on('complete', () => { + this.saveDownloadFile(filePath, fileName, options, uri => { + this.success(new DownloadFileResult(uri), options); + }); + }); + downloadTask.on('fail', errCode => { + this.errorWithCodeAndMsg(new Error(errCode, 'File download fail.'), options); + }); + }).catch((err: BusinessError) => { + this.error(err, options); + }); + } + + getNetworkType(options: GetNetworkTypeOptions): void { + connection.getDefaultNet().then(netHandle => { + if (!netHandle || netHandle.netId === 0) { + this.errorWithCodeAndMsg(NETWORK_NO_ACTIVE_ERROR, options); + return; + } + connection.getNetCapabilities(netHandle).then(netCapabilities => { + let res: GetNetworkTypeResult = new GetNetworkTypeResult(netCapabilities.bearerTypes, netCapabilities.networkCap, + netCapabilities.linkUpBandwidthKbps, netCapabilities.linkDownBandwidthKbps); + this.success(res, options); + }).catch((err: BusinessError) => { + this.error(err, options); + }); + }).catch((err: BusinessError) => { + this.error(err, options); + }); + } + + getLocation(options: GetLocationOptions): void { + this.checkPermissions(PERMISSION_APPROXIMATELY_LOCATION, err => { + if (err) { + this.error(err, options); + return; + } + geoLocationManager.getCurrentLocation({ + priority: options.priority, + scenario: options.scenario, + maxAccuracy: options.maxAccuracy, + timeoutMs: options.timeoutMs + }).then(location => { + let res: GetLocationResult = new GetLocationResult(location.latitude, location.longitude, location.altitude, location.accuracy, location.speed, + location.timeStamp, location.direction, location.timeSinceBoot, location.additions, location.additionSize); + this.success(res, options); + }).catch((err: BusinessError) => { + this.error(err, options); + }); + }); + } +} + +class NavPathInfo { + name: string | undefined; + index: number; + param?: object; + + constructor(name: string | undefined, index: number) { + this.name = name; + this.index = index; + } +} + +class CheckUploadFileResult { + checkResult: boolean; + uriMap?: Map; + + constructor(checkResult: boolean, uriMap?: Map) { + this.checkResult = checkResult; + this.uriMap = uriMap; + } +} + +class BaseOptions { + callback?: (err: Error | undefined, res?: T) => void; +} + +class PushUrlOptions extends BaseOptions { + url?: string; + params?: object; + mode?: string; +} + +class PushUrlResult { +} + +class ReplaceUrlOptions extends BaseOptions { + url?: string; + params?: object; + mode?: string; +} + +class ReplaceUrlResult { +} + +class BackUrlOptions extends BaseOptions { + url?: string; + index?: number; + delta?: number; + params?: object; +} + +class BackUrlResult { +} + +class ClearUrlOptions extends BaseOptions { +} + +class ClearUrlResult { +} + +class OnPopEvent { + name?: string; + param?: object; + result?: object; + + constructor(name?: string, param?: object, result?: object) { + this.name = name; + this.param = param; + this.result = result; + } +} + +class PushPathOptions extends BaseOptions { + name?: string; + param?: object; + animated?: boolean; + onPop?: (event: OnPopEvent) => void; +} + +class PushPathResult { +} + +class ReplacePathOptions extends BaseOptions { + name?: string; + param?: object; + animated?: boolean; + onPop?: (event: OnPopEvent) => void; +} + +class ReplacePathResult { +} + +class PopPathOptions extends BaseOptions { + name?: string; + index?: number; + delta?: number; + result?: object; + animated?: boolean; +} + +class PopPathResult { + name: string | undefined; + index: number; + param?: object; + + constructor(name: string | undefined, index: number, param?: object) { + this.name = name; + this.index = index; + this.param = param; + } +} + +class ClearPathOptions extends BaseOptions { + animated?: boolean; +} + +class ClearPathResult { +} + +class PostMessageOptions extends BaseOptions { + data?: object; +} + +class PostMessageResult { +} + +export class OnMessageEvent { + data?: object[]; +} + +class GetEnvOptions extends BaseOptions { +} + +class GetEnvResult { + deviceType?: string; + brand?: string; + productModel?: string; + osFullName?: string; +} + +class CheckJsApiOptions extends BaseOptions { + jsApiList?: string[]; +} + +class CheckJsApiResult { + checkResult?: Map; + + constructor(checkResult?: Map) { + this.checkResult = checkResult; + } +} + +class PickCameraOptions extends BaseOptions { + mediaTypes?: string[]; + cameraPosition?: number; + saveUri?: string; + videoDuration?: number; +} + +class PickCameraResult { + resultCode?: number; + resultUri?: string; + mediaType?: string; + + constructor(resultCode?: number, resultUri?: string, mediaType?: string) { + this.resultCode = resultCode; + this.resultUri = resultUri; + this.mediaType = mediaType; + } +} + +class SelectPhotoOptions extends BaseOptions { + mimeType?: string; + maxSelectNumber?: number; + isPhotoTakingSupported?: boolean; + isEditSupported?: boolean; + isSearchSupported?: boolean; + recommendationType?: number; + preselectedUris?: string[]; +} + +class SelectPhotoResult { + photoUris?: string[]; + isOriginalPhoto?: boolean; + + constructor(photoUris?: string[], isOriginalPhoto?: boolean) { + this.photoUris = photoUris; + this.isOriginalPhoto = isOriginalPhoto; + } +} + +class OpenPreviewOptions extends BaseOptions { + title?: string; + uri?: string; + mimeType?: string; +} + +class OpenPreviewResult { +} + +class UploadFileOptions extends BaseOptions { + url?: string; + header?: object; + method?: string; + files?: UploadFile[]; + data?: UploadRequestData[]; +} + +class UploadFile { + filename: string; + name: string; + uri: string; + type: string; + + constructor(filename: string, name: string, uri: string, type: string) { + this.filename = filename; + this.name = name; + this.uri = uri; + this.type = type; + } +} + +class UploadRequestData { + name?: string; + value?: string; +} + +class UploadFileResult { + taskStates?: UploadFileTaskState[]; + + constructor(taskStates?: UploadFileTaskState[]) { + this.taskStates = taskStates; + } +} + +class UploadFileTaskState { + path?: string; + responseCode?: number; + message?: string; + + constructor(path?: string, responseCode?: number, message?: string) { + this.path = path; + this.responseCode = responseCode; + this.message = message; + } +} + +class DownloadFileOptions extends BaseOptions { + url?: string; + header?: object; + fileName?: string; + enableMetered?: boolean; + enableRoaming?: boolean; + networkType?: number; +} + +class DownloadFileResult { + uri?: string; + + constructor(uri?: string) { + this.uri = uri; + } +} + +class GetNetworkTypeOptions extends BaseOptions { +} + +class GetNetworkTypeResult { + bearerTypes: number[]; + networkCap?: number[]; + linkUpBandwidthKbps?: number; + linkDownBandwidthKbps?: number; + + constructor(bearerTypes: number[], networkCap?: number[], linkUpBandwidthKbps?: number, linkDownBandwidthKbps?: number) { + this.bearerTypes = bearerTypes; + this.networkCap = networkCap; + this.linkUpBandwidthKbps = linkUpBandwidthKbps; + this.linkDownBandwidthKbps = linkDownBandwidthKbps; + } +} + +class GetLocationOptions extends BaseOptions { + priority?: number; + scenario?: number; + maxAccuracy?: number; + timeoutMs?: number; +} + +class GetLocationResult { + latitude: number; + longitude: number; + altitude: number; + accuracy: number; + speed: number; + timeStamp: number; + direction: number; + timeSinceBoot: number; + additions?: string[] | undefined; + additionSize?: number; + + constructor(latitude: number, longitude: number, altitude: number, accuracy: number, speed: number, + timeStamp: number, direction: number, timeSinceBoot: number, additions?: string[], additionSize?: number) { + this.latitude = latitude; + this.longitude = longitude; + this.altitude = altitude; + this.accuracy = accuracy; + this.speed = speed; + this.timeStamp = timeStamp; + this.direction = direction; + this.timeSinceBoot = timeSinceBoot; + this.additions = additions; + this.additionSize = additionSize; + } +} -- Gitee From 08e6c6c7d690f5932fdc2cab43884ec4571df970 Mon Sep 17 00:00:00 2001 From: txazo Date: Sat, 15 Jun 2024 15:35:42 +0800 Subject: [PATCH 02/10] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=A3=80=E8=A7=86?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: txazo --- .../interfaces/atomicserviceweb.cpp | 42 ++++++++++--------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/advanced_ui_component/atomicserviceweb/interfaces/atomicserviceweb.cpp b/advanced_ui_component/atomicserviceweb/interfaces/atomicserviceweb.cpp index d5a1ffe6e44..b8bf007922f 100644 --- a/advanced_ui_component/atomicserviceweb/interfaces/atomicserviceweb.cpp +++ b/advanced_ui_component/atomicserviceweb/interfaces/atomicserviceweb.cpp @@ -1,3 +1,4 @@ + /* * Copyright (c) 2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); @@ -35,35 +36,36 @@ namespace HMS::AtomicServiceWeb { NAPI_ASSERT(env, argc >= requireArgc, "Wrong number of arguments"); - napi_valuetype valuetype0; - NAPI_CALL(env, napi_typeof(env, args[0], &valuetype0)); + napi_valuetype bundleNameType; + NAPI_CALL(env, napi_typeof(env, args[0], &bundleNameType)); - napi_valuetype valuetype1; - NAPI_CALL(env, napi_typeof(env, args[1], &valuetype1)); + napi_valuetype domainTypeType; + NAPI_CALL(env, napi_typeof(env, args[1], &domainTypeType)); - napi_valuetype valuetype2; - NAPI_CALL(env, napi_typeof(env, args[2], &valuetype2)); + napi_valuetype urlType; + NAPI_CALL(env, napi_typeof(env, args[2], &urlType)); - NAPI_ASSERT(env, valuetype0 == napi_string && valuetype1 == napi_string && valuetype2 == napi_string, "Wrong argument type. String expected."); + NAPI_ASSERT(env, bundleNameType == napi_string && domainTypeType == napi_string && urlType == napi_string, + "Wrong argument type. String expected."); size_t maxValueLen = 1024; - char value0[maxValueLen]; - size_t length0 = 0; - napi_get_value_string_utf8(env, args[0], value0, maxValueLen, &length0); - std::string strValue0 = value0; + char bundleNameValue[maxValueLen]; + size_t bundleNameLength = 0; + napi_get_value_string_utf8(env, args[0], bundleNameValue, maxValueLen, &bundleNameLength); + std::string bundleName = bundleNameValue; - char value1[maxValueLen]; - size_t length1 = 0; - napi_get_value_string_utf8(env, args[1], value1, maxValueLen, &length1); - std::string strValue1 = value1; + char domainTypeValue[maxValueLen]; + size_t domainTypeLength = 0; + napi_get_value_string_utf8(env, args[1], domainTypeValue, maxValueLen, &domainTypeLength); + std::string domainType = domainTypeValue; - char value2[maxValueLen]; - size_t length2 = 0; - napi_get_value_string_utf8(env, args[2], value2, maxValueLen, &length2); - std::string strValue2 = value2; + char urlValue[maxValueLen]; + size_t urlLength = 0; + napi_get_value_string_utf8(env, args[2], urlValue, maxValueLen, &urlLength); + std::string url = urlValue; auto apiPolicyAdapter = new ApiPolicyAdapter(); - int32_t res = apiPolicyAdapter->CheckUrl(strValue0, strValue1, strValue2); + int32_t res = apiPolicyAdapter->CheckUrl(bundleName, domainType, url); napi_value result; NAPI_CALL(env, napi_create_double(env, res, &result)); -- Gitee From bbb2ae921c7ff722191fe1084d1ba2f1f77fb466 Mon Sep 17 00:00:00 2001 From: txazo Date: Sat, 15 Jun 2024 18:10:50 +0800 Subject: [PATCH 03/10] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=A3=80=E6=9F=A5?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: txazo --- .../interfaces/api_policy_adapter.cpp | 9 +- .../interfaces/atomicserviceweb.cpp | 8 +- .../interfaces/atomicserviceweb.js | 27 +- .../interfaces/include/api_policy_adapter.h | 5 + .../source/atomicserviceweb.ets | 272 +++++++++--------- 5 files changed, 175 insertions(+), 146 deletions(-) diff --git a/advanced_ui_component/atomicserviceweb/interfaces/api_policy_adapter.cpp b/advanced_ui_component/atomicserviceweb/interfaces/api_policy_adapter.cpp index 6c0cfbb0601..ab06c855ca5 100644 --- a/advanced_ui_component/atomicserviceweb/interfaces/api_policy_adapter.cpp +++ b/advanced_ui_component/atomicserviceweb/interfaces/api_policy_adapter.cpp @@ -16,21 +16,24 @@ #include "../include/api_policy_adapter.h" #include -ApiPolicyAdapter::ApiPolicyAdapter() { +ApiPolicyAdapter::ApiPolicyAdapter() +{ handle = dlopen("/system/lib64/platformsdk/libapipolicy_client.z.so", RTLD_NOW); if (!handle) { return; } } -ApiPolicyAdapter::~ApiPolicyAdapter() { +ApiPolicyAdapter::~ApiPolicyAdapter() +{ if (handle) { dlclose(handle); handle = nullptr; } } -int32_t ApiPolicyAdapter::CheckUrl(std::string bundleName, std::string domainType, std::string url) { +int32_t ApiPolicyAdapter::CheckUrl(std::string bundleName, std::string domainType, std::string url) +{ int32_t res = -1; using CheckUrl = int32_t (*)(std::string, std::string, std::string); auto func = reinterpret_cast(dlsym(handle, "CheckUrl")); diff --git a/advanced_ui_component/atomicserviceweb/interfaces/atomicserviceweb.cpp b/advanced_ui_component/atomicserviceweb/interfaces/atomicserviceweb.cpp index b8bf007922f..f200d33d552 100644 --- a/advanced_ui_component/atomicserviceweb/interfaces/atomicserviceweb.cpp +++ b/advanced_ui_component/atomicserviceweb/interfaces/atomicserviceweb.cpp @@ -1,4 +1,3 @@ - /* * Copyright (c) 2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); @@ -29,6 +28,7 @@ extern const char _binary_atomicserviceweb_abc_end[]; namespace HMS::AtomicServiceWeb { static napi_value CheckUrl(napi_env env, napi_callback_info info) { + const int indexTwo = 2; size_t requireArgc = 3; size_t argc = 3; napi_value args[3] = { nullptr }; @@ -43,9 +43,9 @@ namespace HMS::AtomicServiceWeb { NAPI_CALL(env, napi_typeof(env, args[1], &domainTypeType)); napi_valuetype urlType; - NAPI_CALL(env, napi_typeof(env, args[2], &urlType)); + NAPI_CALL(env, napi_typeof(env, args[indexTwo], &urlType)); - NAPI_ASSERT(env, bundleNameType == napi_string && domainTypeType == napi_string && urlType == napi_string, + NAPI_ASSERT(env, bundleNameType == napi_string && domainTypeType == napi_string && urlType == napi_string, "Wrong argument type. String expected."); size_t maxValueLen = 1024; @@ -61,7 +61,7 @@ namespace HMS::AtomicServiceWeb { char urlValue[maxValueLen]; size_t urlLength = 0; - napi_get_value_string_utf8(env, args[2], urlValue, maxValueLen, &urlLength); + napi_get_value_string_utf8(env, args[indexTwo], urlValue, maxValueLen, &urlLength); std::string url = urlValue; auto apiPolicyAdapter = new ApiPolicyAdapter(); diff --git a/advanced_ui_component/atomicserviceweb/interfaces/atomicserviceweb.js b/advanced_ui_component/atomicserviceweb/interfaces/atomicserviceweb.js index 222a372baba..9963c82a963 100644 --- a/advanced_ui_component/atomicserviceweb/interfaces/atomicserviceweb.js +++ b/advanced_ui_component/atomicserviceweb/interfaces/atomicserviceweb.js @@ -202,7 +202,8 @@ export class AtomicServiceWeb extends ViewPU { registerJavaScriptProxy() { try { - this.controller.registerJavaScriptProxy(this.atomicServiceProxy, JAVA_SCRIPT_PROXY_OBJECT_NAME, JAVA_SCRIPT_PROXY_API_NAME_LIST); + this.controller.registerJavaScriptProxy(this.atomicServiceProxy, JAVA_SCRIPT_PROXY_OBJECT_NAME, + JAVA_SCRIPT_PROXY_API_NAME_LIST); } catch (y9) { let z9 = y9; console.error(`AtomicServiceWeb registerJavaScriptProxy failed, code is ${z9.code}, message is ${z9.message}`); @@ -285,7 +286,8 @@ class AtomicService { } error(e9, f9) { - f9?.callback && f9?.callback(new Error(e9.code ? e9.code : SYSTEM_INTERNAL_ERROR.code, e9.message ? e9.message : SYSTEM_INTERNAL_ERROR.message)); + f9?.callback && f9?.callback(new Error(e9.code ? e9.code : SYSTEM_INTERNAL_ERROR.code, + e9.message ? e9.message : SYSTEM_INTERNAL_ERROR.message)); } errorWithCodeAndMsg(c9, d9) { @@ -318,7 +320,8 @@ class AtomicService { checkNumberParamPositive(s8, t8, u8) { if (t8 <= 0) { - this.errorWithCodeAndMsg(new Error(PARAM_NUMBER_POSITIVE_ERROR_CODE, `Param ${s8} must be a positive number.`), u8); + this.errorWithCodeAndMsg(new Error(PARAM_NUMBER_POSITIVE_ERROR_CODE, + `Param ${s8} must be a positive number.`), u8); return false; } return true; @@ -381,7 +384,8 @@ class AtomicService { checkNavPathStack(y7, z7) { if (!this.navPathStack) { - this.errorWithCodeAndMsg(new Error(NAV_PATH_STACK_NOT_EXIST_ERROR_CODE, `Current page is not NavDestination, not support ${y7}().`), z7); + this.errorWithCodeAndMsg(new Error(NAV_PATH_STACK_NOT_EXIST_ERROR_CODE, + `Current page is not NavDestination, not support ${y7}().`), z7); return false; } return true; @@ -404,8 +408,8 @@ class AtomicService { getCurrentNavPathInfo() { let s7 = this.navPathStack?.getAllPathName(); - let t7 = (s7 && s7.length > 0) ? new NavPathInfo(s7[s7.length - 1], s7.length - 1) : - new NavPathInfo(undefined, -1); + let t7 = (s7 && s7.length > 0) ? + new NavPathInfo(s7[s7.length - 1], s7.length - 1) : new NavPathInfo(undefined, -1); if (t7.index >= 0) { t7.param = this.navPathStack?.getParamByIndex(t7.index); } @@ -473,7 +477,8 @@ class AtomicService { return new CheckUploadFileResult(false); } if (!z6.uri.startsWith('file://') && !fs.accessSync(z6.uri, fs.AccessModeType.EXIST)) { - this.errorWithCodeAndMsg(new Error(UPLOAD_IMAGE_FILE_NOT_EXIST_ERROR_CODE, `File uri ${z6.uri} is not exist.`), w6); + this.errorWithCodeAndMsg(new Error(UPLOAD_IMAGE_FILE_NOT_EXIST_ERROR_CODE, + `File uri ${z6.uri} is not exist.`), w6); return new CheckUploadFileResult(false); } let a7 = z6.uri; @@ -853,7 +858,8 @@ class AtomicServiceApi extends AtomicService { return; } connection.getNetCapabilities(z1).then(n2 => { - let t2 = new GetNetworkTypeResult(n2.bearerTypes, n2.networkCap, n2.linkUpBandwidthKbps, n2.linkDownBandwidthKbps); + let t2 = new GetNetworkTypeResult(n2.bearerTypes, n2.networkCap, n2.linkUpBandwidthKbps, + n2.linkDownBandwidthKbps); this.success(t2, v1); }).catch((j2) => { this.error(j2, v1); @@ -875,8 +881,9 @@ class AtomicServiceApi extends AtomicService { maxAccuracy: n1.maxAccuracy, timeoutMs: n1.timeoutMs }).then(t1 => { - let u1 = new GetLocationResult(t1.latitude, t1.longitude, t1.altitude, t1.accuracy, t1.speed, t1.timeStamp, t1.direction, t1.timeSinceBoot, - t1.additions, t1.additionSize); + let u1 = + new GetLocationResult(t1.latitude, t1.longitude, t1.altitude, t1.accuracy, t1.speed, t1.timeStamp, + t1.direction, t1.timeSinceBoot, t1.additions, t1.additionSize); this.success(u1, n1); }).catch((s1) => { this.error(s1, n1); diff --git a/advanced_ui_component/atomicserviceweb/interfaces/include/api_policy_adapter.h b/advanced_ui_component/atomicserviceweb/interfaces/include/api_policy_adapter.h index 1813da19a3b..75f3ab062cc 100644 --- a/advanced_ui_component/atomicserviceweb/interfaces/include/api_policy_adapter.h +++ b/advanced_ui_component/atomicserviceweb/interfaces/include/api_policy_adapter.h @@ -13,6 +13,9 @@ * limitations under the License. */ +#ifndef API_POLICY_ADAPTER_H +#define API_POLICY_ADAPTER_H + #include "string" class ApiPolicyAdapter { @@ -25,3 +28,5 @@ public: private: void *handle = nullptr; }; + +#endif diff --git a/advanced_ui_component/atomicserviceweb/source/atomicserviceweb.ets b/advanced_ui_component/atomicserviceweb/source/atomicserviceweb.ets index e09e9450b13..768d1275099 100644 --- a/advanced_ui_component/atomicserviceweb/source/atomicserviceweb.ets +++ b/advanced_ui_component/atomicserviceweb/source/atomicserviceweb.ets @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + import web_webview from '@ohos.web.webview'; import router from '@ohos.router'; import deviceInfo from '@ohos.deviceInfo'; @@ -61,7 +61,8 @@ const UPLOAD_IMAGE_CACHE_DIR: string = '/cache/'; const JAVA_SCRIPT_PROXY_OBJECT_NAME: string = 'atomicServiceProxy'; const JAVA_SCRIPT_PROXY_API_NAME_LIST: string[] = ['invokeJsApi']; const ATOMIC_SERVICE_JS_API_MAP = new Map(); -const registerJsApi = (apiNameAlias: string, apiName: string, minVersion: string, maxVersion: string, requiredFieldNames: string[]): void => { +const registerJsApi = (apiNameAlias: string, apiName: string, minVersion: string, maxVersion: string, + requiredFieldNames: string[]): void => { ATOMIC_SERVICE_JS_API_MAP.set(apiNameAlias, new JsApiConfig(apiName, minVersion, maxVersion, requiredFieldNames)); }; const MAX_VERSION = '99.99.99'; @@ -109,8 +110,8 @@ const NETWORK_NO_ACTIVE_ERROR: Error = new Error(200015, 'The network is not act @Component export struct AtomicServiceWeb { @Prop src: ResourceStr; - navPathStack?: NavPathStack; - onMessage?: (event?: OnMessageEvent) => void = () => { + public navPathStack?: NavPathStack; + public onMessage?: (event?: OnMessageEvent) => void = () => { }; private context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext; private controller: web_webview.WebviewController = new web_webview.WebviewController(); @@ -154,7 +155,8 @@ export struct AtomicServiceWeb { registerJavaScriptProxy(): void { try { - this.controller.registerJavaScriptProxy(this.atomicServiceProxy, JAVA_SCRIPT_PROXY_OBJECT_NAME, JAVA_SCRIPT_PROXY_API_NAME_LIST); + this.controller.registerJavaScriptProxy(this.atomicServiceProxy, JAVA_SCRIPT_PROXY_OBJECT_NAME, + JAVA_SCRIPT_PROXY_API_NAME_LIST); } catch (error) { let e: BusinessError = error as BusinessError; console.error(`AtomicServiceWeb registerJavaScriptProxy failed, code is ${e.code}, message is ${e.message}`); @@ -212,13 +214,14 @@ class AtomicServiceProxy { } class AtomicService { - context: common.UIAbilityContext; - navPathStack?: NavPathStack; - messageDataList: object[] = []; - onMessage: (event?: OnMessageEvent) => void = () => { + protected context: common.UIAbilityContext; + protected navPathStack?: NavPathStack; + protected messageDataList: object[] = []; + protected onMessage: (event?: OnMessageEvent) => void = () => { }; - constructor(context: common.UIAbilityContext, navPathStack?: NavPathStack, onMessage?: (event?: OnMessageEvent) => void) { + constructor(context: common.UIAbilityContext, navPathStack?: NavPathStack, + onMessage?: (event?: OnMessageEvent) => void) { this.context = context; this.navPathStack = navPathStack; this.onMessage = onMessage ? onMessage : this.onMessage; @@ -263,7 +266,8 @@ class AtomicService { checkNumberParamPositive(paramKey: string, paramValue: number, options: BaseOptions): boolean { if (paramValue <= 0) { - this.errorWithCodeAndMsg(new Error(PARAM_NUMBER_POSITIVE_ERROR_CODE, `Param ${paramKey} must be a positive number.`), options); + this.errorWithCodeAndMsg(new Error(PARAM_NUMBER_POSITIVE_ERROR_CODE, + `Param ${paramKey} must be a positive number.`), options); return false; } return true; @@ -326,7 +330,8 @@ class AtomicService { checkNavPathStack(apiName: string, options: BaseOptions): boolean { if (!this.navPathStack) { - this.errorWithCodeAndMsg(new Error(NAV_PATH_STACK_NOT_EXIST_ERROR_CODE, `Current page is not NavDestination, not support ${apiName}().`), options); + this.errorWithCodeAndMsg(new Error(NAV_PATH_STACK_NOT_EXIST_ERROR_CODE, + `Current page is not NavDestination, not support ${apiName}().`), options); return false; } return true; @@ -349,8 +354,8 @@ class AtomicService { getCurrentNavPathInfo(): NavPathInfo { let navPathStack: Array | undefined = this.navPathStack?.getAllPathName(); - let navPathInfo: NavPathInfo = (navPathStack && navPathStack.length > 0) ? new NavPathInfo(navPathStack[navPathStack.length - 1], navPathStack.length - 1) : - new NavPathInfo(undefined, -1); + let navPathInfo: NavPathInfo = (navPathStack && navPathStack.length > 0) ? + new NavPathInfo(navPathStack[navPathStack.length - 1], navPathStack.length - 1) : new NavPathInfo(undefined, -1); if (navPathInfo.index >= 0) { navPathInfo.param = this.navPathStack?.getParamByIndex(navPathInfo.index) as object; } @@ -418,7 +423,8 @@ class AtomicService { return new CheckUploadFileResult(false); } if (!file.uri.startsWith('file://') && !fs.accessSync(file.uri, fs.AccessModeType.EXIST)) { - this.errorWithCodeAndMsg(new Error(UPLOAD_IMAGE_FILE_NOT_EXIST_ERROR_CODE, `File uri ${file.uri} is not exist.`), options); + this.errorWithCodeAndMsg(new Error(UPLOAD_IMAGE_FILE_NOT_EXIST_ERROR_CODE, + `File uri ${file.uri} is not exist.`), options); return new CheckUploadFileResult(false); } let originUri: string = file.uri; @@ -470,12 +476,14 @@ class AtomicService { return requestFiles; } - handleUploadFileResult(taskStateArray: Array, uriMap: Map, options: UploadFileOptions): void { + handleUploadFileResult(taskStateArray: Array, uriMap: Map, + options: UploadFileOptions): void { let taskStates: UploadFileTaskState[] = []; if (taskStateArray) { taskStateArray.forEach(taskState => { let path: (string | undefined) = taskState.path ? uriMap.get(taskState.path) : taskState.path; - taskStates.push(new UploadFileTaskState(path ? path : taskState.path, taskState.responseCode, taskState.message)); + taskStates.push(new UploadFileTaskState(path ? path : taskState.path, taskState.responseCode, + taskState.message)); }); } this.success(new UploadFileResult(taskStates), options); @@ -496,7 +504,8 @@ class AtomicService { return http.substring(index + 1); } - saveDownloadFile(filePath: string, fileName: string, options: DownloadFileOptions, callback: (uri: string) => void): void { + saveDownloadFile(filePath: string, fileName: string, options: DownloadFileOptions, + callback: (uri: string) => void): void { let documentPicker = new filePicker.DocumentViewPicker(); documentPicker.save({ newFileNames: [fileName] @@ -513,7 +522,8 @@ class AtomicService { } checkAccessToken(permissionName: Permissions): Promise { - let bundleInfo: bundleManager.BundleInfo = bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION); + let bundleInfo: bundleManager.BundleInfo = bundleManager.getBundleInfoForSelfSync( + bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION); let tokenId: number = bundleInfo.appInfo.accessTokenId; let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager(); return atManager.checkAccessToken(tokenId, permissionName); @@ -543,7 +553,8 @@ class AtomicService { } class AtomicServiceApi extends AtomicService { - constructor(context: common.UIAbilityContext, navPathStack?: NavPathStack, onMessage?: (event?: OnMessageEvent) => void) { + constructor(context: common.UIAbilityContext, navPathStack?: NavPathStack, + onMessage?: (event?: OnMessageEvent) => void) { super(context, navPathStack, onMessage); } @@ -691,7 +702,8 @@ class AtomicServiceApi extends AtomicService { saveUri: options.saveUri, videoDuration: options.videoDuration }).then((pickerResult: picker.PickerResult) => { - this.success(new PickCameraResult(pickerResult.resultCode, pickerResult.resultUri, pickerResult.mediaType), options); + this.success(new PickCameraResult(pickerResult.resultCode, pickerResult.resultUri, pickerResult.mediaType), + options); }).catch((err: BusinessError) => { this.error(err, options); }); @@ -798,8 +810,8 @@ class AtomicServiceApi extends AtomicService { return; } connection.getNetCapabilities(netHandle).then(netCapabilities => { - let res: GetNetworkTypeResult = new GetNetworkTypeResult(netCapabilities.bearerTypes, netCapabilities.networkCap, - netCapabilities.linkUpBandwidthKbps, netCapabilities.linkDownBandwidthKbps); + let res: GetNetworkTypeResult = new GetNetworkTypeResult(netCapabilities.bearerTypes, + netCapabilities.networkCap, netCapabilities.linkUpBandwidthKbps, netCapabilities.linkDownBandwidthKbps); this.success(res, options); }).catch((err: BusinessError) => { this.error(err, options); @@ -821,8 +833,9 @@ class AtomicServiceApi extends AtomicService { maxAccuracy: options.maxAccuracy, timeoutMs: options.timeoutMs }).then(location => { - let res: GetLocationResult = new GetLocationResult(location.latitude, location.longitude, location.altitude, location.accuracy, location.speed, - location.timeStamp, location.direction, location.timeSinceBoot, location.additions, location.additionSize); + let res: GetLocationResult = new GetLocationResult(location.latitude, location.longitude, location.altitude, + location.accuracy, location.speed, location.timeStamp, location.direction, location.timeSinceBoot, + location.additions, location.additionSize); this.success(res, options); }).catch((err: BusinessError) => { this.error(err, options); @@ -832,9 +845,9 @@ class AtomicServiceApi extends AtomicService { } class NavPathInfo { - name: string | undefined; - index: number; - param?: object; + public name: string | undefined; + public index: number; + public param?: object; constructor(name: string | undefined, index: number) { this.name = name; @@ -843,8 +856,8 @@ class NavPathInfo { } class CheckUploadFileResult { - checkResult: boolean; - uriMap?: Map; + public checkResult: boolean; + public uriMap?: Map; constructor(checkResult: boolean, uriMap?: Map) { this.checkResult = checkResult; @@ -853,32 +866,32 @@ class CheckUploadFileResult { } class BaseOptions { - callback?: (err: Error | undefined, res?: T) => void; + public callback?: (err: Error | undefined, res?: T) => void; } class PushUrlOptions extends BaseOptions { - url?: string; - params?: object; - mode?: string; + public url?: string; + public params?: object; + public mode?: string; } class PushUrlResult { } class ReplaceUrlOptions extends BaseOptions { - url?: string; - params?: object; - mode?: string; + public url?: string; + public params?: object; + public mode?: string; } class ReplaceUrlResult { } class BackUrlOptions extends BaseOptions { - url?: string; - index?: number; - delta?: number; - params?: object; + public url?: string; + public index?: number; + public delta?: number; + public params?: object; } class BackUrlResult { @@ -891,9 +904,9 @@ class ClearUrlResult { } class OnPopEvent { - name?: string; - param?: object; - result?: object; + public name?: string; + public param?: object; + public result?: object; constructor(name?: string, param?: object, result?: object) { this.name = name; @@ -903,37 +916,37 @@ class OnPopEvent { } class PushPathOptions extends BaseOptions { - name?: string; - param?: object; - animated?: boolean; - onPop?: (event: OnPopEvent) => void; + public name?: string; + public param?: object; + public animated?: boolean; + public onPop?: (event: OnPopEvent) => void; } class PushPathResult { } class ReplacePathOptions extends BaseOptions { - name?: string; - param?: object; - animated?: boolean; - onPop?: (event: OnPopEvent) => void; + public name?: string; + public param?: object; + public animated?: boolean; + public onPop?: (event: OnPopEvent) => void; } class ReplacePathResult { } class PopPathOptions extends BaseOptions { - name?: string; - index?: number; - delta?: number; - result?: object; - animated?: boolean; + public name?: string; + public index?: number; + public delta?: number; + public result?: object; + public animated?: boolean; } class PopPathResult { - name: string | undefined; - index: number; - param?: object; + public name: string | undefined; + public index: number; + public param?: object; constructor(name: string | undefined, index: number, param?: object) { this.name = name; @@ -943,39 +956,39 @@ class PopPathResult { } class ClearPathOptions extends BaseOptions { - animated?: boolean; + public animated?: boolean; } class ClearPathResult { } class PostMessageOptions extends BaseOptions { - data?: object; + public data?: object; } class PostMessageResult { } export class OnMessageEvent { - data?: object[]; + public data?: object[]; } class GetEnvOptions extends BaseOptions { } class GetEnvResult { - deviceType?: string; - brand?: string; - productModel?: string; - osFullName?: string; + public deviceType?: string; + public brand?: string; + public productModel?: string; + public osFullName?: string; } class CheckJsApiOptions extends BaseOptions { - jsApiList?: string[]; + public jsApiList?: string[]; } class CheckJsApiResult { - checkResult?: Map; + public checkResult?: Map; constructor(checkResult?: Map) { this.checkResult = checkResult; @@ -983,16 +996,16 @@ class CheckJsApiResult { } class PickCameraOptions extends BaseOptions { - mediaTypes?: string[]; - cameraPosition?: number; - saveUri?: string; - videoDuration?: number; + public mediaTypes?: string[]; + public cameraPosition?: number; + public saveUri?: string; + public videoDuration?: number; } class PickCameraResult { - resultCode?: number; - resultUri?: string; - mediaType?: string; + public resultCode?: number; + public resultUri?: string; + public mediaType?: string; constructor(resultCode?: number, resultUri?: string, mediaType?: string) { this.resultCode = resultCode; @@ -1002,18 +1015,18 @@ class PickCameraResult { } class SelectPhotoOptions extends BaseOptions { - mimeType?: string; - maxSelectNumber?: number; - isPhotoTakingSupported?: boolean; - isEditSupported?: boolean; - isSearchSupported?: boolean; - recommendationType?: number; - preselectedUris?: string[]; + public mimeType?: string; + public maxSelectNumber?: number; + public isPhotoTakingSupported?: boolean; + public isEditSupported?: boolean; + public isSearchSupported?: boolean; + public recommendationType?: number; + public preselectedUris?: string[]; } class SelectPhotoResult { - photoUris?: string[]; - isOriginalPhoto?: boolean; + public photoUris?: string[]; + public isOriginalPhoto?: boolean; constructor(photoUris?: string[], isOriginalPhoto?: boolean) { this.photoUris = photoUris; @@ -1022,27 +1035,27 @@ class SelectPhotoResult { } class OpenPreviewOptions extends BaseOptions { - title?: string; - uri?: string; - mimeType?: string; + public title?: string; + public uri?: string; + public mimeType?: string; } class OpenPreviewResult { } class UploadFileOptions extends BaseOptions { - url?: string; - header?: object; - method?: string; - files?: UploadFile[]; - data?: UploadRequestData[]; + public url?: string; + public header?: object; + public method?: string; + public files?: UploadFile[]; + public data?: UploadRequestData[]; } class UploadFile { - filename: string; - name: string; - uri: string; - type: string; + public filename: string; + public name: string; + public uri: string; + public type: string; constructor(filename: string, name: string, uri: string, type: string) { this.filename = filename; @@ -1053,12 +1066,12 @@ class UploadFile { } class UploadRequestData { - name?: string; - value?: string; + public name?: string; + public value?: string; } class UploadFileResult { - taskStates?: UploadFileTaskState[]; + public taskStates?: UploadFileTaskState[]; constructor(taskStates?: UploadFileTaskState[]) { this.taskStates = taskStates; @@ -1066,9 +1079,9 @@ class UploadFileResult { } class UploadFileTaskState { - path?: string; - responseCode?: number; - message?: string; + public path?: string; + public responseCode?: number; + public message?: string; constructor(path?: string, responseCode?: number, message?: string) { this.path = path; @@ -1078,16 +1091,16 @@ class UploadFileTaskState { } class DownloadFileOptions extends BaseOptions { - url?: string; - header?: object; - fileName?: string; - enableMetered?: boolean; - enableRoaming?: boolean; - networkType?: number; + public url?: string; + public header?: object; + public fileName?: string; + public enableMetered?: boolean; + public enableRoaming?: boolean; + public networkType?: number; } class DownloadFileResult { - uri?: string; + public uri?: string; constructor(uri?: string) { this.uri = uri; @@ -1098,12 +1111,13 @@ class GetNetworkTypeOptions extends BaseOptions { } class GetNetworkTypeResult { - bearerTypes: number[]; - networkCap?: number[]; - linkUpBandwidthKbps?: number; - linkDownBandwidthKbps?: number; + public bearerTypes: number[]; + public networkCap?: number[]; + public linkUpBandwidthKbps?: number; + public linkDownBandwidthKbps?: number; - constructor(bearerTypes: number[], networkCap?: number[], linkUpBandwidthKbps?: number, linkDownBandwidthKbps?: number) { + constructor(bearerTypes: number[], networkCap?: number[], linkUpBandwidthKbps?: number, + linkDownBandwidthKbps?: number) { this.bearerTypes = bearerTypes; this.networkCap = networkCap; this.linkUpBandwidthKbps = linkUpBandwidthKbps; @@ -1112,23 +1126,23 @@ class GetNetworkTypeResult { } class GetLocationOptions extends BaseOptions { - priority?: number; - scenario?: number; - maxAccuracy?: number; - timeoutMs?: number; + public priority?: number; + public scenario?: number; + public maxAccuracy?: number; + public timeoutMs?: number; } class GetLocationResult { - latitude: number; - longitude: number; - altitude: number; - accuracy: number; - speed: number; - timeStamp: number; - direction: number; - timeSinceBoot: number; - additions?: string[] | undefined; - additionSize?: number; + public latitude: number; + public longitude: number; + public altitude: number; + public accuracy: number; + public speed: number; + public timeStamp: number; + public direction: number; + public timeSinceBoot: number; + public additions?: string[] | undefined; + public additionSize?: number; constructor(latitude: number, longitude: number, altitude: number, accuracy: number, speed: number, timeStamp: number, direction: number, timeSinceBoot: number, additions?: string[], additionSize?: number) { -- Gitee From e86a8802e893a8d50ea2a93d0aedc87dcc094355 Mon Sep 17 00:00:00 2001 From: txazo Date: Sat, 15 Jun 2024 18:24:22 +0800 Subject: [PATCH 04/10] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=A3=80=E6=9F=A5?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: txazo --- .../atomicserviceweb/source/atomicserviceweb.ets | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/advanced_ui_component/atomicserviceweb/source/atomicserviceweb.ets b/advanced_ui_component/atomicserviceweb/source/atomicserviceweb.ets index 768d1275099..0c14cdc7337 100644 --- a/advanced_ui_component/atomicserviceweb/source/atomicserviceweb.ets +++ b/advanced_ui_component/atomicserviceweb/source/atomicserviceweb.ets @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + import web_webview from '@ohos.web.webview'; import router from '@ohos.router'; import deviceInfo from '@ohos.deviceInfo'; @@ -42,10 +42,10 @@ class Error { } class JsApiConfig { - apiName: string; - minVersion: string; - maxVersion: string; - requiredFieldNames?: string[]; + public apiName: string; + public minVersion: string; + public maxVersion: string; + public requiredFieldNames?: string[]; constructor(apiName: string, minVersion: string, maxVersion: string, requiredFieldNames?: string[]) { this.apiName = apiName; -- Gitee From 2b2d3c723132cb40ef2c55a85e749a4de2a465d1 Mon Sep 17 00:00:00 2001 From: txazo Date: Sat, 15 Jun 2024 18:37:44 +0800 Subject: [PATCH 05/10] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=A3=80=E6=9F=A5?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: txazo --- .../atomicserviceweb/interfaces/BUILD.gn | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/advanced_ui_component/atomicserviceweb/interfaces/BUILD.gn b/advanced_ui_component/atomicserviceweb/interfaces/BUILD.gn index 2338cb7b74a..b977f52c144 100644 --- a/advanced_ui_component/atomicserviceweb/interfaces/BUILD.gn +++ b/advanced_ui_component/atomicserviceweb/interfaces/BUILD.gn @@ -47,12 +47,18 @@ gen_obj("atomicserviceweb_abc_preview") { ohos_shared_library("atomicserviceweb") { include_dirs = [ "include" ] - sources = [ "atomicserviceweb.cpp", "api_policy_adapter.cpp" ] + sources = [ + "api_policy_adapter.cpp", + "atomicserviceweb.cpp", + ] if (use_mingw_win || use_mac || use_linux) { deps = [ ":gen_obj_src_atomicserviceweb_abc_preview" ] } else { - deps = [ ":atomicserviceweb_js", ":atomicserviceweb_abc" ] + deps = [ + ":atomicserviceweb_abc", + ":atomicserviceweb_js", + ] } external_deps = [ -- Gitee From 757b4e5fdc6263418fbb52ed6bca78a1c9843d92 Mon Sep 17 00:00:00 2001 From: txazo Date: Sat, 15 Jun 2024 19:14:44 +0800 Subject: [PATCH 06/10] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=A3=80=E6=9F=A5?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: txazo --- .../atomicserviceweb/source/atomicserviceweb.ets | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/advanced_ui_component/atomicserviceweb/source/atomicserviceweb.ets b/advanced_ui_component/atomicserviceweb/source/atomicserviceweb.ets index 0c14cdc7337..a4877ea9e79 100644 --- a/advanced_ui_component/atomicserviceweb/source/atomicserviceweb.ets +++ b/advanced_ui_component/atomicserviceweb/source/atomicserviceweb.ets @@ -32,8 +32,8 @@ import filePicker from '@ohos.file.picker'; import { BusinessError } from '@ohos.base'; class Error { - code: number; - message: string; + public code: number; + public message: string; constructor(code: number, message: string) { this.code = code; -- Gitee From b90fcc53ec3161f79f27487b20d89d90fecd7054 Mon Sep 17 00:00:00 2001 From: txazo Date: Mon, 17 Jun 2024 15:17:52 +0800 Subject: [PATCH 07/10] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=A3=80=E8=A7=86?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: txazo --- .../atomicserviceweb/interfaces/api_policy_adapter.cpp | 8 ++++---- .../interfaces/{include => }/api_policy_adapter.h | 7 ++++++- .../atomicserviceweb/interfaces/atomicserviceweb.cpp | 3 ++- 3 files changed, 12 insertions(+), 6 deletions(-) rename advanced_ui_component/atomicserviceweb/interfaces/{include => }/api_policy_adapter.h (74%) diff --git a/advanced_ui_component/atomicserviceweb/interfaces/api_policy_adapter.cpp b/advanced_ui_component/atomicserviceweb/interfaces/api_policy_adapter.cpp index ab06c855ca5..5b5ed31a45c 100644 --- a/advanced_ui_component/atomicserviceweb/interfaces/api_policy_adapter.cpp +++ b/advanced_ui_component/atomicserviceweb/interfaces/api_policy_adapter.cpp @@ -1,3 +1,4 @@ + /* * Copyright (c) 2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); @@ -13,7 +14,7 @@ * limitations under the License. */ -#include "../include/api_policy_adapter.h" +#include "api_policy_adapter.h" #include ApiPolicyAdapter::ApiPolicyAdapter() @@ -22,6 +23,7 @@ ApiPolicyAdapter::ApiPolicyAdapter() if (!handle) { return; } + func = reinterpret_cast(dlsym(handle, "CheckUrl")); } ApiPolicyAdapter::~ApiPolicyAdapter() @@ -32,11 +34,9 @@ ApiPolicyAdapter::~ApiPolicyAdapter() } } -int32_t ApiPolicyAdapter::CheckUrl(std::string bundleName, std::string domainType, std::string url) +int32_t ApiPolicyAdapter::CheckUrl(const std::string& bundleName, const std::string& domainType, const std::string& url) { int32_t res = -1; - using CheckUrl = int32_t (*)(std::string, std::string, std::string); - auto func = reinterpret_cast(dlsym(handle, "CheckUrl")); if (func == nullptr) { return res; } diff --git a/advanced_ui_component/atomicserviceweb/interfaces/include/api_policy_adapter.h b/advanced_ui_component/atomicserviceweb/interfaces/api_policy_adapter.h similarity index 74% rename from advanced_ui_component/atomicserviceweb/interfaces/include/api_policy_adapter.h rename to advanced_ui_component/atomicserviceweb/interfaces/api_policy_adapter.h index 75f3ab062cc..69a4e267f2e 100644 --- a/advanced_ui_component/atomicserviceweb/interfaces/include/api_policy_adapter.h +++ b/advanced_ui_component/atomicserviceweb/interfaces/api_policy_adapter.h @@ -1,3 +1,4 @@ + /* * Copyright (c) 2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); @@ -23,10 +24,14 @@ public: ApiPolicyAdapter(); ~ApiPolicyAdapter(); - int32_t CheckUrl(std::string bundleName, std::string domainType, std::string url); + int32_t CheckUrl(const std::string& bundleName, const std::string& domainType, const std::string& url); + + using CheckUrlFunc = int32_t (*)(const std::string&, const std::string&, const std::string&); + void SetCheckUrlFunc(CheckUrlFunc& func); private: void *handle = nullptr; + CheckUrlFunc func = nullptr; }; #endif diff --git a/advanced_ui_component/atomicserviceweb/interfaces/atomicserviceweb.cpp b/advanced_ui_component/atomicserviceweb/interfaces/atomicserviceweb.cpp index f200d33d552..871902cba6d 100644 --- a/advanced_ui_component/atomicserviceweb/interfaces/atomicserviceweb.cpp +++ b/advanced_ui_component/atomicserviceweb/interfaces/atomicserviceweb.cpp @@ -1,3 +1,4 @@ + /* * Copyright (c) 2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,7 +17,7 @@ #include "native_engine/native_engine.h" #include "napi/native_api.h" #include "napi/native_node_api.h" -#include "../include/api_policy_adapter.h" +#include "api_policy_adapter.h" using namespace std; -- Gitee From 3302100c2659ae2cf1d084341a89dd8cedb9c6c5 Mon Sep 17 00:00:00 2001 From: txazo Date: Tue, 25 Jun 2024 20:02:28 +0800 Subject: [PATCH 08/10] =?UTF-8?q?AtomicServiceWeb=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E4=BA=8B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: txazo --- .../interfaces/api_policy_adapter.cpp | 1 - .../interfaces/api_policy_adapter.h | 1 - .../interfaces/atomicserviceweb.cpp | 1 - .../interfaces/atomicserviceweb.js | 81 ++++++++++++++----- .../source/atomicserviceweb.ets | 76 ++++++++++++++--- 5 files changed, 125 insertions(+), 35 deletions(-) diff --git a/advanced_ui_component/atomicserviceweb/interfaces/api_policy_adapter.cpp b/advanced_ui_component/atomicserviceweb/interfaces/api_policy_adapter.cpp index 5b5ed31a45c..81f3e6d4cbb 100644 --- a/advanced_ui_component/atomicserviceweb/interfaces/api_policy_adapter.cpp +++ b/advanced_ui_component/atomicserviceweb/interfaces/api_policy_adapter.cpp @@ -1,4 +1,3 @@ - /* * Copyright (c) 2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/advanced_ui_component/atomicserviceweb/interfaces/api_policy_adapter.h b/advanced_ui_component/atomicserviceweb/interfaces/api_policy_adapter.h index 69a4e267f2e..dfca0a49a10 100644 --- a/advanced_ui_component/atomicserviceweb/interfaces/api_policy_adapter.h +++ b/advanced_ui_component/atomicserviceweb/interfaces/api_policy_adapter.h @@ -1,4 +1,3 @@ - /* * Copyright (c) 2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/advanced_ui_component/atomicserviceweb/interfaces/atomicserviceweb.cpp b/advanced_ui_component/atomicserviceweb/interfaces/atomicserviceweb.cpp index 871902cba6d..0bc1996f07a 100644 --- a/advanced_ui_component/atomicserviceweb/interfaces/atomicserviceweb.cpp +++ b/advanced_ui_component/atomicserviceweb/interfaces/atomicserviceweb.cpp @@ -1,4 +1,3 @@ - /* * Copyright (c) 2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/advanced_ui_component/atomicserviceweb/interfaces/atomicserviceweb.js b/advanced_ui_component/atomicserviceweb/interfaces/atomicserviceweb.js index 9963c82a963..7d3de0118a7 100644 --- a/advanced_ui_component/atomicserviceweb/interfaces/atomicserviceweb.js +++ b/advanced_ui_component/atomicserviceweb/interfaces/atomicserviceweb.js @@ -105,10 +105,18 @@ export class AtomicServiceWeb extends ViewPU { if (typeof s10 === "function") { this.paramsGenerator_ = s10; } - this.__src = new SynchedPropertyObjectOneWayPU(p10.src, this, "src"); + this.src = undefined; this.navPathStack = undefined; this.onMessage = () => { }; + this.onErrorReceive = () => { + }; + this.onHttpErrorReceive = () => { + }; + this.onPageBegin = () => { + }; + this.onPageEnd = () => { + }; this.context = getContext(this); this.controller = new web_webview.WebviewController(); this.schemeHandler = new web_webview.WebSchemeHandler(); @@ -119,12 +127,27 @@ export class AtomicServiceWeb extends ViewPU { } setInitiallyProvidedValue(n10) { + if (n10.src !== undefined) { + this.src = n10.src; + } if (n10.navPathStack !== undefined) { this.navPathStack = n10.navPathStack; } if (n10.onMessage !== undefined) { this.onMessage = n10.onMessage; } + if (n10.onErrorReceive !== undefined) { + this.onErrorReceive = n10.onErrorReceive; + } + if (n10.onHttpErrorReceive !== undefined) { + this.onHttpErrorReceive = n10.onHttpErrorReceive; + } + if (n10.onPageBegin !== undefined) { + this.onPageBegin = n10.onPageBegin; + } + if (n10.onPageEnd !== undefined) { + this.onPageEnd = n10.onPageEnd; + } if (n10.context !== undefined) { this.context = n10.context; } @@ -143,27 +166,16 @@ export class AtomicServiceWeb extends ViewPU { } updateStateVars(m10) { - this.__src.reset(m10.src); } purgeVariableDependenciesOnElmtId(l10) { - this.__src.purgeDependencyOnElmtId(l10); } aboutToBeDeleted() { - this.__src.aboutToBeDeleted(); SubscriberManager.Get().delete(this.id__()); this.aboutToBeDeletedInternal(); } - get src() { - return this.__src.get(); - } - - set src(k10) { - this.__src.set(k10); - } - aboutToAppear() { if (!this.atomicService) { this.atomicService = new AtomicServiceApi(this.context, this.navPathStack, this.onMessage); @@ -178,12 +190,14 @@ export class AtomicServiceWeb extends ViewPU { initialRender() { this.observeComponentCreation2((b10, c10) => { Web.create({ src: this.src, controller: this.controller }); - Web.fileAccess(true); - Web.imageAccess(true); - Web.onlineImageAccess(true); - Web.javaScriptAccess(true); - Web.domStorageAccess(true); - Web.geolocationAccess(true); + Web.zoomAccess(false); + Web.overviewModeAccess(false); + Web.allowWindowOpenMethod(false); + Web.layoutMode(WebLayoutMode.NONE); + Web.onErrorReceive(this.onErrorReceive); + Web.onHttpErrorReceive(this.onHttpErrorReceive); + Web.onPageBegin(this.onPageBegin); + Web.onPageEnd(this.onPageEnd); Web.onControllerAttached(() => { this.registerJavaScriptProxy(); this.schemeHandler.onRequestStart((j10) => { @@ -420,7 +434,7 @@ class AtomicService { if (this.messageDataList.length <= 0) { return; } - this.onMessage({ data: this.messageDataList }); + this.onMessage(new OnMessageEvent(this.messageDataList)); this.messageDataList = []; } @@ -977,6 +991,35 @@ class PostMessageResult { } export class OnMessageEvent { + constructor(c2) { + this.data = c2; + } +} + +export class OnErrorReceiveEvent { + constructor(r4, v4) { + this.request = r4; + this.error = v4; + } +} + +export class OnHttpErrorReceiveEvent { + constructor(r3, w3) { + this.request = r3; + this.response = w3; + } +} + +export class OnPageBeginEvent { + constructor(e2) { + this.url = e2; + } +} + +export class OnPageEndEvent { + constructor(d2) { + this.url = d2; + } } class GetEnvOptions extends BaseOptions { diff --git a/advanced_ui_component/atomicserviceweb/source/atomicserviceweb.ets b/advanced_ui_component/atomicserviceweb/source/atomicserviceweb.ets index a4877ea9e79..c04e4b21317 100644 --- a/advanced_ui_component/atomicserviceweb/source/atomicserviceweb.ets +++ b/advanced_ui_component/atomicserviceweb/source/atomicserviceweb.ets @@ -109,9 +109,17 @@ const NETWORK_NO_ACTIVE_ERROR: Error = new Error(200015, 'The network is not act @Component export struct AtomicServiceWeb { - @Prop src: ResourceStr; + public src: ResourceStr | undefined = undefined; public navPathStack?: NavPathStack; - public onMessage?: (event?: OnMessageEvent) => void = () => { + public onMessage?: (event: OnMessageEvent) => void = () => { + }; + public onErrorReceive?: (event?: OnErrorReceiveEvent) => void = () => { + }; + public onHttpErrorReceive?: (event?: OnHttpErrorReceiveEvent) => void = () => { + }; + public onPageBegin?: (event?: OnPageBeginEvent) => void = () => { + }; + public onPageEnd?: (event?: OnPageEndEvent) => void = () => { }; private context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext; private controller: web_webview.WebviewController = new web_webview.WebviewController(); @@ -132,12 +140,14 @@ export struct AtomicServiceWeb { build() { Web({ src: this.src, controller: this.controller }) - .fileAccess(true) - .imageAccess(true) - .onlineImageAccess(true) - .javaScriptAccess(true) - .domStorageAccess(true) - .geolocationAccess(true) + .zoomAccess(false) + .overviewModeAccess(false) + .allowWindowOpenMethod(false) + .layoutMode(WebLayoutMode.NONE) + .onErrorReceive(this.onErrorReceive) + .onHttpErrorReceive(this.onHttpErrorReceive) + .onPageBegin(this.onPageBegin) + .onPageEnd(this.onPageEnd) .onControllerAttached(() => { this.registerJavaScriptProxy(); this.schemeHandler.onRequestStart((request: web_webview.WebSchemeHandlerRequest) => { @@ -217,11 +227,11 @@ class AtomicService { protected context: common.UIAbilityContext; protected navPathStack?: NavPathStack; protected messageDataList: object[] = []; - protected onMessage: (event?: OnMessageEvent) => void = () => { + protected onMessage: (event: OnMessageEvent) => void = () => { }; constructor(context: common.UIAbilityContext, navPathStack?: NavPathStack, - onMessage?: (event?: OnMessageEvent) => void) { + onMessage?: (event: OnMessageEvent) => void) { this.context = context; this.navPathStack = navPathStack; this.onMessage = onMessage ? onMessage : this.onMessage; @@ -366,7 +376,7 @@ class AtomicService { if (this.messageDataList.length <= 0) { return; } - this.onMessage({ data: this.messageDataList }); + this.onMessage(new OnMessageEvent(this.messageDataList)); this.messageDataList = []; } @@ -554,7 +564,7 @@ class AtomicService { class AtomicServiceApi extends AtomicService { constructor(context: common.UIAbilityContext, navPathStack?: NavPathStack, - onMessage?: (event?: OnMessageEvent) => void) { + onMessage?: (event: OnMessageEvent) => void) { super(context, navPathStack, onMessage); } @@ -970,7 +980,47 @@ class PostMessageResult { } export class OnMessageEvent { - public data?: object[]; + public data: object[]; + + constructor(data: object[]) { + this.data = data; + } +} + +export class OnErrorReceiveEvent { + public request: WebResourceRequest; + public error: WebResourceError; + + constructor(request: WebResourceRequest, error: WebResourceError) { + this.request = request; + this.error = error; + } +} + +export class OnHttpErrorReceiveEvent { + public request: WebResourceRequest; + public response: WebResourceResponse; + + constructor(request: WebResourceRequest, response: WebResourceResponse) { + this.request = request; + this.response = response; + } +} + +export class OnPageBeginEvent { + public url: string; + + constructor(url: string) { + this.url = url; + } +} + +export class OnPageEndEvent { + public url: string; + + constructor(url: string) { + this.url = url; + } } class GetEnvOptions extends BaseOptions { -- Gitee From 0e6e6de144f9b950f38f62194be8c7578603a298 Mon Sep 17 00:00:00 2001 From: txazo Date: Tue, 9 Jul 2024 09:54:49 +0800 Subject: [PATCH 09/10] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=B8=BACallback?= =?UTF-8?q?=E6=96=B9=E6=B3=95=E5=A3=B0=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: txazo --- .../atomicserviceweb/source/atomicserviceweb.ets | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/advanced_ui_component/atomicserviceweb/source/atomicserviceweb.ets b/advanced_ui_component/atomicserviceweb/source/atomicserviceweb.ets index c04e4b21317..15048be67ee 100644 --- a/advanced_ui_component/atomicserviceweb/source/atomicserviceweb.ets +++ b/advanced_ui_component/atomicserviceweb/source/atomicserviceweb.ets @@ -111,15 +111,15 @@ const NETWORK_NO_ACTIVE_ERROR: Error = new Error(200015, 'The network is not act export struct AtomicServiceWeb { public src: ResourceStr | undefined = undefined; public navPathStack?: NavPathStack; - public onMessage?: (event: OnMessageEvent) => void = () => { + public onMessage?: Callback = () => { }; - public onErrorReceive?: (event?: OnErrorReceiveEvent) => void = () => { + public onErrorReceive?: Callback = () => { }; - public onHttpErrorReceive?: (event?: OnHttpErrorReceiveEvent) => void = () => { + public onHttpErrorReceive?: Callback = () => { }; - public onPageBegin?: (event?: OnPageBeginEvent) => void = () => { + public onPageBegin?: Callback = () => { }; - public onPageEnd?: (event?: OnPageEndEvent) => void = () => { + public onPageEnd?: Callback = () => { }; private context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext; private controller: web_webview.WebviewController = new web_webview.WebviewController(); -- Gitee From a45e083345c35b8ef86911982bf4aae22def92c8 Mon Sep 17 00:00:00 2001 From: txazo Date: Tue, 9 Jul 2024 20:09:29 +0800 Subject: [PATCH 10/10] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=A3=80=E8=A7=86?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: txazo --- .../interfaces/atomicserviceweb.js | 972 +++++++++--------- .../source/atomicserviceweb.ets | 95 +- 2 files changed, 533 insertions(+), 534 deletions(-) diff --git a/advanced_ui_component/atomicserviceweb/interfaces/atomicserviceweb.js b/advanced_ui_component/atomicserviceweb/interfaces/atomicserviceweb.js index 7d3de0118a7..8466b344603 100644 --- a/advanced_ui_component/atomicserviceweb/interfaces/atomicserviceweb.js +++ b/advanced_ui_component/atomicserviceweb/interfaces/atomicserviceweb.js @@ -34,19 +34,19 @@ const picker = requireNapi('multimedia.cameraPicker'); const filePicker = requireNapi('file.picker'); const atomicServiceWebNapi = requireInternal('atomicservice.AtomicServiceWeb'); -class Error { - constructor(e11, f11) { - this.code = e11; - this.message = f11; +class AsError { + constructor(m11, n11) { + this.code = m11; + this.message = n11; } } class JsApiConfig { - constructor(a11, b11, c11, d11) { - this.apiName = a11; - this.minVersion = b11; - this.maxVersion = c11; - this.requiredFieldNames = d11; + constructor(i11, j11, k11, l11) { + this.apiName = i11; + this.minVersion = j11; + this.maxVersion = k11; + this.requiredFieldNames = l11; } } @@ -56,54 +56,53 @@ const UPLOAD_IMAGE_CACHE_DIR = '/cache/'; const JAVA_SCRIPT_PROXY_OBJECT_NAME = 'atomicServiceProxy'; const JAVA_SCRIPT_PROXY_API_NAME_LIST = ['invokeJsApi']; const ATOMIC_SERVICE_JS_API_MAP = new Map(); -const registerJsApi = (v10, w10, x10, y10, z10) => { - ATOMIC_SERVICE_JS_API_MAP.set(v10, new JsApiConfig(w10, x10, y10, z10)); +const registerJsApi = (d11, e11, f11, g11, h11) => { + ATOMIC_SERVICE_JS_API_MAP.set(d11, new JsApiConfig(e11, f11, g11, h11)); }; const MAX_VERSION = '99.99.99'; const ATOMIC_SERVICE_JS_SDK_CURRENT_VERSION = '1.0.0'; const PERMISSION_APPROXIMATELY_LOCATION = 'ohos.permission.APPROXIMATELY_LOCATION'; -const SYSTEM_INTERNAL_ERROR = new Error(500, 'System internal error.'); -const JS_API_INVALID_INVOKE_ERROR = new Error(200001, 'Invalid invoke.'); +const SYSTEM_INTERNAL_ERROR = new AsError(500, 'System internal error.'); +const JS_API_INVALID_INVOKE_ERROR = new AsError(200001, 'Invalid invoke.'); const PARAM_REQUIRED_ERROR_CODE = 200002; const PARAM_NUMBER_POSITIVE_ERROR_CODE = 200003; -const ROUTER_PARAM_MODE_INVALID_ERROR = new Error(200004, 'Param mode is invalid.'); -const BACK_URL_NOT_EXIST_OR_OPENED_ERROR = new Error(200005, 'Url is not exist or opened, can not be back.'); +const ROUTER_PARAM_MODE_INVALID_ERROR = new AsError(200004, 'Param mode is invalid.'); +const BACK_URL_NOT_EXIST_OR_OPENED_ERROR = new AsError(200005, 'Url is not exist or opened, can not be back.'); const NAV_PATH_STACK_NOT_EXIST_ERROR_CODE = 200006; -const POP_PATH_NAME_NOT_EXIST_ERROR = new Error(200007, 'Name is not exist or opened, can not be pop.'); -const POP_PATH_PARAM_INDEX_INVALID_ERROR = new Error(200008, 'Param index is invalid.'); -const POP_PATH_INDEX_OUT_OF_RANGE_ERROR = new Error(200009, 'The Index is out of range.'); -const UPLOAD_IMAGE_FILES_REQUIRED_ERROR = new Error(200010, 'Param files is required.'); +const POP_PATH_NAME_NOT_EXIST_ERROR = new AsError(200007, 'Name is not exist or opened, can not be pop.'); +const POP_PATH_PARAM_INDEX_INVALID_ERROR = new AsError(200008, 'Param index is invalid.'); +const POP_PATH_INDEX_OUT_OF_RANGE_ERROR = new AsError(200009, 'The Index is out of range.'); +const UPLOAD_IMAGE_FILES_REQUIRED_ERROR = new AsError(200010, 'Param files is required.'); const UPLOAD_IMAGE_FILE_NOT_EXIST_ERROR_CODE = 200011; -const UPLOAD_IMAGE_FILES_URI_REQUIRED_ERROR = new Error(200012, 'Param uri of files is required.'); -const UPLOAD_FILE_ERROR = new Error(200013, 'Upload file error.'); -const IMAGE_CAN_NOT_PREVIEW_ERROR = new Error(200014, 'The filePath can not preview.'); -const NETWORK_NO_ACTIVE_ERROR = new Error(200015, 'The network is not active.'); -{ - registerJsApi('router.pushUrl', 'pushUrl', '1.0.0', MAX_VERSION, ['url']); - registerJsApi('router.replaceUrl', 'replaceUrl', '1.0.0', MAX_VERSION, ['url']); - registerJsApi('router.back', 'backUrl', '1.0.0', MAX_VERSION, []); - registerJsApi('router.clear', 'clearUrl', '1.0.0', MAX_VERSION, []); - registerJsApi('navPathStack.pushPath', 'pushPath', '1.0.0', MAX_VERSION, ['name']); - registerJsApi('navPathStack.replacePath', 'replacePath', '1.0.0', MAX_VERSION, ['name']); - registerJsApi('navPathStack.pop', 'popPath', '1.0.0', MAX_VERSION, []); - registerJsApi('navPathStack.clear', 'clearPath', '1.0.0', MAX_VERSION, []); - registerJsApi('asWeb.postMessage', 'postMessage', '1.0.0', MAX_VERSION, ['data']); - registerJsApi('asWeb.getEnv', 'getEnv', '1.0.0', MAX_VERSION, []); - registerJsApi('asWeb.checkJsApi', 'checkJsApi', '1.0.0', MAX_VERSION, ['jsApiList']); - registerJsApi('cameraPicker.pick', 'pickCamera', '1.0.0', MAX_VERSION, ['mediaTypes', 'cameraPosition']); - registerJsApi('photoViewPicker.select', 'selectPhoto', '1.0.0', MAX_VERSION, []); - registerJsApi('filePreview.openPreview', 'openPreview', '1.0.0', MAX_VERSION, ['uri']); - registerJsApi('request.uploadFile', 'uploadFile', '1.0.0', MAX_VERSION, ['url', 'files']); - registerJsApi('request.downloadFile', 'downloadFile', '1.0.0', MAX_VERSION, ['url']); - registerJsApi('connection.getNetworkType', 'getNetworkType', '1.0.0', MAX_VERSION, []); - registerJsApi('location.getLocation', 'getLocation', '1.0.0', MAX_VERSION, []); -} +const UPLOAD_IMAGE_FILES_URI_REQUIRED_ERROR = new AsError(200012, 'Param uri of files is required.'); +const UPLOAD_FILE_ERROR = new AsError(200013, 'Upload file error.'); +const IMAGE_CAN_NOT_PREVIEW_ERROR = new AsError(200014, 'The filePath can not preview.'); +const NETWORK_NO_ACTIVE_ERROR = new AsError(200015, 'The network is not active.'); + +registerJsApi('router.pushUrl', 'pushUrl', '1.0.0', MAX_VERSION, ['url']); +registerJsApi('router.replaceUrl', 'replaceUrl', '1.0.0', MAX_VERSION, ['url']); +registerJsApi('router.back', 'backUrl', '1.0.0', MAX_VERSION, []); +registerJsApi('router.clear', 'clearUrl', '1.0.0', MAX_VERSION, []); +registerJsApi('navPathStack.pushPath', 'pushPath', '1.0.0', MAX_VERSION, ['name']); +registerJsApi('navPathStack.replacePath', 'replacePath', '1.0.0', MAX_VERSION, ['name']); +registerJsApi('navPathStack.pop', 'popPath', '1.0.0', MAX_VERSION, []); +registerJsApi('navPathStack.clear', 'clearPath', '1.0.0', MAX_VERSION, []); +registerJsApi('asWeb.postMessage', 'postMessage', '1.0.0', MAX_VERSION, ['data']); +registerJsApi('asWeb.getEnv', 'getEnv', '1.0.0', MAX_VERSION, []); +registerJsApi('asWeb.checkJsApi', 'checkJsApi', '1.0.0', MAX_VERSION, ['jsApiList']); +registerJsApi('cameraPicker.pick', 'pickCamera', '1.0.0', MAX_VERSION, ['mediaTypes', 'cameraPosition']); +registerJsApi('photoViewPicker.select', 'selectPhoto', '1.0.0', MAX_VERSION, []); +registerJsApi('filePreview.openPreview', 'openPreview', '1.0.0', MAX_VERSION, ['uri']); +registerJsApi('request.uploadFile', 'uploadFile', '1.0.0', MAX_VERSION, ['url', 'files']); +registerJsApi('request.downloadFile', 'downloadFile', '1.0.0', MAX_VERSION, ['url']); +registerJsApi('connection.getNetworkType', 'getNetworkType', '1.0.0', MAX_VERSION, []); +registerJsApi('location.getLocation', 'getLocation', '1.0.0', MAX_VERSION, []); export class AtomicServiceWeb extends ViewPU { - constructor(o10, p10, q10, r10 = -1, s10 = undefined, t10) { - super(o10, q10, r10, t10); - if (typeof s10 === "function") { - this.paramsGenerator_ = s10; + constructor(s10, t10, u10, v10 = -1, w10 = undefined, x10) { + super(s10, u10, v10, x10); + if (typeof w10 === "function") { + this.paramsGenerator_ = w10; } this.src = undefined; this.navPathStack = undefined; @@ -117,58 +116,58 @@ export class AtomicServiceWeb extends ViewPU { }; this.onPageEnd = () => { }; - this.context = getContext(this); + this.context = this.getUIContext().getHostContext(); this.controller = new web_webview.WebviewController(); this.schemeHandler = new web_webview.WebSchemeHandler(); this.atomicService = undefined; this.atomicServiceProxy = undefined; - this.setInitiallyProvidedValue(p10); + this.setInitiallyProvidedValue(t10); this.finalizeConstruction(); } - setInitiallyProvidedValue(n10) { - if (n10.src !== undefined) { - this.src = n10.src; + setInitiallyProvidedValue(r10) { + if (r10.src !== undefined) { + this.src = r10.src; } - if (n10.navPathStack !== undefined) { - this.navPathStack = n10.navPathStack; + if (r10.navPathStack !== undefined) { + this.navPathStack = r10.navPathStack; } - if (n10.onMessage !== undefined) { - this.onMessage = n10.onMessage; + if (r10.onMessage !== undefined) { + this.onMessage = r10.onMessage; } - if (n10.onErrorReceive !== undefined) { - this.onErrorReceive = n10.onErrorReceive; + if (r10.onErrorReceive !== undefined) { + this.onErrorReceive = r10.onErrorReceive; } - if (n10.onHttpErrorReceive !== undefined) { - this.onHttpErrorReceive = n10.onHttpErrorReceive; + if (r10.onHttpErrorReceive !== undefined) { + this.onHttpErrorReceive = r10.onHttpErrorReceive; } - if (n10.onPageBegin !== undefined) { - this.onPageBegin = n10.onPageBegin; + if (r10.onPageBegin !== undefined) { + this.onPageBegin = r10.onPageBegin; } - if (n10.onPageEnd !== undefined) { - this.onPageEnd = n10.onPageEnd; + if (r10.onPageEnd !== undefined) { + this.onPageEnd = r10.onPageEnd; } - if (n10.context !== undefined) { - this.context = n10.context; + if (r10.context !== undefined) { + this.context = r10.context; } - if (n10.controller !== undefined) { - this.controller = n10.controller; + if (r10.controller !== undefined) { + this.controller = r10.controller; } - if (n10.schemeHandler !== undefined) { - this.schemeHandler = n10.schemeHandler; + if (r10.schemeHandler !== undefined) { + this.schemeHandler = r10.schemeHandler; } - if (n10.atomicService !== undefined) { - this.atomicService = n10.atomicService; + if (r10.atomicService !== undefined) { + this.atomicService = r10.atomicService; } - if (n10.atomicServiceProxy !== undefined) { - this.atomicServiceProxy = n10.atomicServiceProxy; + if (r10.atomicServiceProxy !== undefined) { + this.atomicServiceProxy = r10.atomicServiceProxy; } } - updateStateVars(m10) { + updateStateVars(q10) { } - purgeVariableDependenciesOnElmtId(l10) { + purgeVariableDependenciesOnElmtId(p10) { } aboutToBeDeleted() { @@ -188,7 +187,7 @@ export class AtomicServiceWeb extends ViewPU { } initialRender() { - this.observeComponentCreation2((b10, c10) => { + this.observeComponentCreation2((g10, h10) => { Web.create({ src: this.src, controller: this.controller }); Web.zoomAccess(false); Web.overviewModeAccess(false); @@ -200,16 +199,16 @@ export class AtomicServiceWeb extends ViewPU { Web.onPageEnd(this.onPageEnd); Web.onControllerAttached(() => { this.registerJavaScriptProxy(); - this.schemeHandler.onRequestStart((j10) => { - return !this.checkUrl(j10.getRequestUrl()); + this.schemeHandler.onRequestStart((o10) => { + return !this.checkUrl(o10.getRequestUrl()); }); this.controller.setWebSchemeHandler('https', this.schemeHandler); }); - Web.onOverrideUrlLoading((h10) => { - return !this.checkUrl(h10.getRequestUrl()); + Web.onOverrideUrlLoading((m10) => { + return !this.checkUrl(m10.getRequestUrl()); }); - Web.onLoadIntercept(g10 => { - return !this.checkUrl(g10.data.getRequestUrl()); + Web.onLoadIntercept(l10 => { + return !this.checkUrl(l10.data.getRequestUrl()); }); }, Web); } @@ -218,20 +217,20 @@ export class AtomicServiceWeb extends ViewPU { try { this.controller.registerJavaScriptProxy(this.atomicServiceProxy, JAVA_SCRIPT_PROXY_OBJECT_NAME, JAVA_SCRIPT_PROXY_API_NAME_LIST); - } catch (y9) { - let z9 = y9; - console.error(`AtomicServiceWeb registerJavaScriptProxy failed, code is ${z9.code}, message is ${z9.message}`); + } catch (d10) { + let e10 = d10; + console.error(`AtomicServiceWeb registerJavaScriptProxy failed, code is ${e10.code}, message is ${e10.message}`); } } - cutUrl(q1) { - if (q1) { - let a2 = q1.indexOf('?'); - if (a2 > -1) { - return q1.substring(0, a2); + cutUrl(b10) { + if (b10) { + let c10 = b10.indexOf('?'); + if (c10 > -1) { + return b10.substring(0, c10); } } - return q1; + return b10; } checkUrl(q1) { @@ -261,173 +260,173 @@ export class AtomicServiceWeb extends ViewPU { } class AtomicServiceProxy { - constructor(r9) { - this.atomicService = r9; + constructor(z9) { + this.atomicService = z9; } - invokeJsApi(m9, n9) { + invokeJsApi(u9, v9) { try { - n9 = n9 || {}; - if (!m9 || !ATOMIC_SERVICE_JS_API_MAP.has(m9)) { - this.atomicService.errorWithCodeAndMsg(JS_API_INVALID_INVOKE_ERROR, n9); + v9 = v9 || {}; + if (!u9 || !ATOMIC_SERVICE_JS_API_MAP.has(u9)) { + this.atomicService.errorWithCodeAndMsg(JS_API_INVALID_INVOKE_ERROR, v9); return; } - this.atomicService.logOptions(m9, n9); - let p9 = ATOMIC_SERVICE_JS_API_MAP.get(m9); - if (!this.atomicService.checkRequiredFieldInOptions(p9, n9)) { + this.atomicService.logOptions(u9, v9); + let x9 = ATOMIC_SERVICE_JS_API_MAP.get(u9); + if (!this.atomicService.checkRequiredFieldInOptions(x9, v9)) { return; } - let q9 = this.atomicService; - q9[p9?.apiName](n9); - } catch (o9) { - this.atomicService.error(o9, n9); + let y9 = this.atomicService; + y9[x9?.apiName](v9); + } catch (w9) { + this.atomicService.error(w9, v9); } } } class AtomicService { - constructor(i9, j9, k9) { + constructor(q9, r9, s9) { this.messageDataList = []; this.onMessage = () => { }; - this.context = i9; - this.navPathStack = j9; - this.onMessage = k9 ? k9 : this.onMessage; + this.context = q9; + this.navPathStack = r9; + this.onMessage = s9 ? s9 : this.onMessage; } - success(g9, h9) { - h9?.callback && h9?.callback(undefined, g9); + success(o9, p9) { + p9?.callback && p9?.callback(undefined, o9); } - error(e9, f9) { - f9?.callback && f9?.callback(new Error(e9.code ? e9.code : SYSTEM_INTERNAL_ERROR.code, - e9.message ? e9.message : SYSTEM_INTERNAL_ERROR.message)); + error(m9, n9) { + n9?.callback && n9?.callback(new AsError(m9.code ? m9.code : SYSTEM_INTERNAL_ERROR.code, + m9.message ? m9.message : SYSTEM_INTERNAL_ERROR.message)); } - errorWithCodeAndMsg(c9, d9) { - d9?.callback && d9?.callback(c9); + errorWithCodeAndMsg(k9, l9) { + l9?.callback && l9?.callback(k9); } - consoleLog(b9) { + consoleLog(j9) { if (LOG_ENABLE) { - console.log(`${LOG_PREFIX} ${b9}`); + console.log(`${LOG_PREFIX} ${j9}`); } } - consoleError(a9) { + consoleError(i9) { if (LOG_ENABLE) { - console.error(`${LOG_PREFIX} ${a9}`); + console.error(`${LOG_PREFIX} ${i9}`); } } - logOptions(y8, z8) { - this.consoleLog(`${y8} options=${JSON.stringify(z8)}`); + logOptions(g9, h9) { + this.consoleLog(`${g9} options=${JSON.stringify(h9)}`); } - checkParamRequired(v8, w8, x8) { - if (w8 === undefined || w8 === null || w8 === '') { - this.errorWithCodeAndMsg(new Error(PARAM_REQUIRED_ERROR_CODE, `Param ${v8} is required.`), x8); + checkParamRequired(d9, e9, f9) { + if (e9 === undefined || e9 === null || e9 === '') { + this.errorWithCodeAndMsg(new AsError(PARAM_REQUIRED_ERROR_CODE, `Param ${d9} is required.`), f9); return false; } return true; } - checkNumberParamPositive(s8, t8, u8) { - if (t8 <= 0) { - this.errorWithCodeAndMsg(new Error(PARAM_NUMBER_POSITIVE_ERROR_CODE, - `Param ${s8} must be a positive number.`), u8); + checkNumberParamPositive(a9, b9, c9) { + if (b9 <= 0) { + this.errorWithCodeAndMsg(new AsError(PARAM_NUMBER_POSITIVE_ERROR_CODE, + `Param ${a9} must be a positive number.`), c9); return false; } return true; } - checkRequiredFieldInOptions(n8, o8) { - if (!n8) { + checkRequiredFieldInOptions(v8, w8) { + if (!v8) { return false; } - if (!n8.requiredFieldNames) { + if (!v8.requiredFieldNames) { return true; } - let p8 = o8; - for (let i3 = 0; i3 < n8.requiredFieldNames.length; i3++) { - let m3 = n8.requiredFieldNames[i3]; - if (!this.checkParamRequired(m3, p8[m3], o8)) { + let x8 = w8; + for (let y8 = 0; y8 < v8.requiredFieldNames.length; y8++) { + let z8 = v8.requiredFieldNames[y8]; + if (!this.checkParamRequired(z8, x8[z8], w8)) { return false; } } return true; } - checkRouterMode(l8, m8) { - if (!l8 || l8 === 'Single' || l8 === 'Standard') { + checkRouterMode(t8, u8) { + if (!t8 || t8 === 'Single' || t8 === 'Standard') { return true; } - this.errorWithCodeAndMsg(ROUTER_PARAM_MODE_INVALID_ERROR, m8); + this.errorWithCodeAndMsg(ROUTER_PARAM_MODE_INVALID_ERROR, u8); return false; } - parseRouterMode(k8) { - return k8 === 'Single' ? router.RouterMode.Single : router.RouterMode.Standard; + parseRouterMode(s8) { + return s8 === 'Single' ? router.RouterMode.Single : router.RouterMode.Standard; } - getRouterIndexByDelta(g8) { - let h8 = parseInt(router.getLength()); - for (let i8 = h8; i8 > 0; i8--) { - let j8 = router.getStateByIndex(i8); - if (j8?.name && g8-- == 0) { - return i8; + getRouterIndexByDelta(o8) { + let p8 = Number.parseInt(router.getLength()); + for (let q8 = p8; q8 > 0; q8--) { + let r8 = router.getStateByIndex(q8); + if (r8?.name && o8-- == 0) { + return q8; } } return 1; } - checkBackUrlExists(a8, b8) { - let c8 = parseInt(router.getLength()); - for (let d8 = c8; d8 > 0; d8--) { - let e8 = router.getStateByIndex(d8); - if (e8?.name) { - let f8 = e8?.path + e8?.name; - if (f8 === a8) { + checkBackUrlExists(i8, j8) { + let k8 = Number.parseInt(router.getLength()); + for (let l8 = k8; l8 > 0; l8--) { + let m8 = router.getStateByIndex(l8); + if (m8?.name) { + let n8 = m8?.path + m8?.name; + if (n8 === i8) { return true; } } } - this.errorWithCodeAndMsg(BACK_URL_NOT_EXIST_OR_OPENED_ERROR, b8); + this.errorWithCodeAndMsg(BACK_URL_NOT_EXIST_OR_OPENED_ERROR, j8); return false; } - checkNavPathStack(y7, z7) { + checkNavPathStack(g8, h8) { if (!this.navPathStack) { - this.errorWithCodeAndMsg(new Error(NAV_PATH_STACK_NOT_EXIST_ERROR_CODE, - `Current page is not NavDestination, not support ${y7}().`), z7); + this.errorWithCodeAndMsg(new AsError(NAV_PATH_STACK_NOT_EXIST_ERROR_CODE, + `Current page is not NavDestination, not support ${g8}().`), h8); return false; } return true; } - getNavPathIndexByDelta(w7) { - let x7 = this.navPathStack?.getAllPathName(); - if (!x7 || x7.length == 0) { + getNavPathIndexByDelta(e8) { + let f8 = this.navPathStack?.getAllPathName(); + if (!f8 || f8.length == 0) { return -1; } - return x7.length > w7 ? (x7.length - w7 - 1) : -1; + return f8.length > e8 ? (f8.length - e8 - 1) : -1; } - onPopHandler(u7, v7) { - if (!u7?.info || !v7) { + onPopHandler(c8, d8) { + if (!c8?.info || !d8) { return; } - v7(new OnPopEvent(u7.info.name, u7.info.param, u7.result)); + d8(new OnPopEvent(c8.info.name, c8.info.param, c8.result)); } getCurrentNavPathInfo() { - let s7 = this.navPathStack?.getAllPathName(); - let t7 = (s7 && s7.length > 0) ? - new NavPathInfo(s7[s7.length - 1], s7.length - 1) : new NavPathInfo(undefined, -1); - if (t7.index >= 0) { - t7.param = this.navPathStack?.getParamByIndex(t7.index); + let a8 = this.navPathStack?.getAllPathName(); + let b8 = (a8 && a8.length > 0) ? + new NavPathInfo(a8[a8.length - 1], a8.length - 1) : new NavPathInfo(undefined, -1); + if (b8.index >= 0) { + b8.param = this.navPathStack?.getParamByIndex(b8.index); } - return t7; + return b8; } notifyMessage() { @@ -438,485 +437,486 @@ class AtomicService { this.messageDataList = []; } - isJsApiEnable(q7) { - if (!q7) { + isJsApiEnable(z7) { + if (!z7) { return false; } - if (this.compareVersion(q7.minVersion, ATOMIC_SERVICE_JS_SDK_CURRENT_VERSION) && - this.compareVersion(ATOMIC_SERVICE_JS_SDK_CURRENT_VERSION, q7.maxVersion)) { + if (this.compareVersion(z7.minVersion, ATOMIC_SERVICE_JS_SDK_CURRENT_VERSION) && + this.compareVersion(ATOMIC_SERVICE_JS_SDK_CURRENT_VERSION, z7.maxVersion)) { return true; } return false; } - compareVersion(h7, i7) { - if (!h7 || !i7) { + compareVersion(p7, q7) { + if (!p7 || !q7) { return false; } - let j7 = h7.split('.').map(p7 => parseInt(p7)); - let k7 = i7.split('.').map(o7 => parseInt(o7)); - for (let n7 = 0; n7 < j7.length && n7 < k7.length; n7++) { - if (j7[n7] < k7[n7]) { + let r7 = p7.split('.').map(y7 => Number.parseInt(y7)); + let s7 = q7.split('.').map(x7 => Number.parseInt(x7)); + const t7 = Math.max(r7.length, s7.length); + for (let w7 = 0; w7 < t7; w7++) { + if (r7[w7] < s7[w7]) { return true; - } else if (j7[n7] > k7[n7]) { + } else if (r7[w7] > s7[w7]) { return false; } } - if (j7.length < k7.length) { + if (r7.length < s7.length) { return true; } - if (j7.length > k7.length) { + if (r7.length > s7.length) { return false; } return true; } - getUri(g7) { - if (!g7 || g7.startsWith('file://')) { - return g7; + getUri(o7) { + if (!o7 || o7.startsWith('file://')) { + return o7; } - return fileUri.getUriFromPath(g7); + return fileUri.getUriFromPath(o7); } - async checkUploadFile(w6) { - if (!w6.files || w6.files.length <= 0) { - this.errorWithCodeAndMsg(UPLOAD_IMAGE_FILES_REQUIRED_ERROR, w6); + async checkUploadFile(e7) { + if (!e7.files || e7.files.length <= 0) { + this.errorWithCodeAndMsg(UPLOAD_IMAGE_FILES_REQUIRED_ERROR, e7); return new CheckUploadFileResult(false); } - let x6 = new Map(); - for (let y6 = 0; y6 < w6.files?.length; y6++) { - let z6 = w6.files[y6]; - if (!z6.uri) { - this.errorWithCodeAndMsg(UPLOAD_IMAGE_FILES_URI_REQUIRED_ERROR, w6); + let f7 = new Map(); + for (let g7 = 0; g7 < e7.files?.length; g7++) { + let h7 = e7.files[g7]; + if (!h7.uri) { + this.errorWithCodeAndMsg(UPLOAD_IMAGE_FILES_URI_REQUIRED_ERROR, e7); return new CheckUploadFileResult(false); } - if (!z6.uri.startsWith('file://') && !fs.accessSync(z6.uri, fs.AccessModeType.EXIST)) { - this.errorWithCodeAndMsg(new Error(UPLOAD_IMAGE_FILE_NOT_EXIST_ERROR_CODE, - `File uri ${z6.uri} is not exist.`), w6); + if (!h7.uri.startsWith('file://') && !fs.accessSync(h7.uri, fs.AccessModeType.EXIST)) { + this.errorWithCodeAndMsg(new AsError(UPLOAD_IMAGE_FILE_NOT_EXIST_ERROR_CODE, + `File uri ${h7.uri} is not exist.`), e7); return new CheckUploadFileResult(false); } - let a7 = z6.uri; - let b7 = z6.uri; - if (b7.indexOf(UPLOAD_IMAGE_CACHE_DIR) < 0) { - let c7 = true; - let d7 = b7.startsWith('file://') ? b7 : fileUri.getUriFromPath(z6.uri); - b7 = this.context.cacheDir + '/' + b7.substring(b7.lastIndexOf('/') + 1); - await fs.copy(d7, fileUri.getUriFromPath(b7)).catch((f7) => { - this.error(f7, w6); - c7 = false; + let i7 = h7.uri; + let j7 = h7.uri; + if (j7.indexOf(UPLOAD_IMAGE_CACHE_DIR) < 0) { + let k7 = true; + let l7 = j7.startsWith('file://') ? j7 : fileUri.getUriFromPath(h7.uri); + j7 = this.context.cacheDir + '/' + j7.substring(j7.lastIndexOf('/') + 1); + await fs.copy(l7, fileUri.getUriFromPath(j7)).catch((n7) => { + this.error(n7, e7); + k7 = false; }); - if (!c7) { - this.errorWithCodeAndMsg(UPLOAD_FILE_ERROR, w6); + if (!k7) { + this.errorWithCodeAndMsg(UPLOAD_FILE_ERROR, e7); return new CheckUploadFileResult(false); } } - z6.uri = 'internal://' + b7.substring(b7.indexOf(UPLOAD_IMAGE_CACHE_DIR) + 1); - x6.set(b7, a7); + h7.uri = 'internal://' + j7.substring(j7.indexOf(UPLOAD_IMAGE_CACHE_DIR) + 1); + f7.set(j7, i7); } - return new CheckUploadFileResult(true, x6); + return new CheckUploadFileResult(true, f7); } - convertToRequestData(s6) { - let t6 = []; - if (s6) { - s6.forEach(v6 => { - if (!v6.name || !v6.value) { + convertToRequestData(a7) { + let b7 = []; + if (a7) { + a7.forEach(d7 => { + if (!d7.name || !d7.value) { return; } - t6.push({ name: v6.name, value: v6.value }); + b7.push({ name: d7.name, value: d7.value }); }); } - return t6; - } - - convertToFile(o6) { - let p6 = []; - if (o6) { - o6.forEach(r6 => { - p6.push({ - filename: r6.filename, - name: r6.name, - uri: r6.uri, - type: r6.type + return b7; + } + + convertToFile(w6) { + let x6 = []; + if (w6) { + w6.forEach(z6 => { + x6.push({ + filename: z6.filename, + name: z6.name, + uri: z6.uri, + type: z6.type }); }); } - return p6; + return x6; } - handleUploadFileResult(h6, i6, j6) { - let k6 = []; - if (h6) { - h6.forEach(m6 => { - let n6 = m6.path ? i6.get(m6.path) : m6.path; - k6.push(new UploadFileTaskState(n6 ? n6 : m6.path, m6.responseCode, m6.message)); + handleUploadFileResult(p6, q6, r6) { + let s6 = []; + if (p6) { + p6.forEach(u6 => { + let v6 = u6.path ? q6.get(u6.path) : u6.path; + s6.push(new UploadFileTaskState(v6 ? v6 : u6.path, u6.responseCode, u6.message)); }); } - this.success(new UploadFileResult(k6), j6); + this.success(new UploadFileResult(s6), r6); } - parseFileNameFromUrl(e6) { - if (!e6) { + parseFileNameFromUrl(m6) { + if (!m6) { return ''; } - let f6 = e6.split('?')[0]; - if (f6.indexOf('/') < 0) { + let n6 = m6.split('?')[0]; + if (n6.indexOf('/') < 0) { return ''; } - let g6 = f6.lastIndexOf('/'); - if (g6 == (f6.length - 1)) { + let o6 = n6.lastIndexOf('/'); + if (o6 == (n6.length - 1)) { return ''; } - return f6.substring(g6 + 1); - } - - saveDownloadFile(r5, s5, t5, u5) { - let v5 = new filePicker.DocumentViewPicker(); - v5.save({ - newFileNames: [s5] - }).then(z5 => { - let a6 = z5[0]; - fs.copy(fileUri.getUriFromPath(r5), a6).then(() => { - u5 && u5(a6); - }).catch((d6) => { - this.error(d6, t5); + return n6.substring(o6 + 1); + } + + saveDownloadFile(z5, a6, b6, c6) { + let d6 = new filePicker.DocumentViewPicker(); + d6.save({ + newFileNames: [a6] + }).then(h6 => { + let i6 = h6[0]; + fs.copy(fileUri.getUriFromPath(z5), i6).then(() => { + c6 && c6(i6); + }).catch((l6) => { + this.error(l6, b6); }); - }).catch((y5) => { - this.error(y5, t5); + }).catch((g6) => { + this.error(g6, b6); }); } - checkAccessToken(n5) { - let o5 = bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION); - let p5 = o5.appInfo.accessTokenId; - let q5 = abilityAccessCtrl.createAtManager(); - return q5.checkAccessToken(p5, n5); + checkAccessToken(v5) { + let w5 = bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION); + let x5 = w5.appInfo.accessTokenId; + let y5 = abilityAccessCtrl.createAtManager(); + return y5.checkAccessToken(x5, v5); } - checkPermissions(b5, c5) { - this.checkAccessToken(b5).then(g5 => { - if (g5 == abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) { - c5(undefined); + checkPermissions(j5, k5) { + this.checkAccessToken(j5).then(o5 => { + if (o5 == abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) { + k5(undefined); } else { - let h5 = abilityAccessCtrl.createAtManager(); - h5.requestPermissionsFromUser(this.context, [b5]).then(l5 => { - for (let m5 = 0; m5 < l5.authResults.length; m5++) { - if (l5.authResults[m5] != 0) { + let p5 = abilityAccessCtrl.createAtManager(); + p5.requestPermissionsFromUser(this.context, [j5]).then(t5 => { + for (let u5 = 0; u5 < t5.authResults.length; u5++) { + if (t5.authResults[u5] != 0) { return; } } - c5(undefined); - }).catch((k5) => { - c5(k5); + k5(undefined); + }).catch((s5) => { + k5(s5); }); } - }).catch((f5) => { - c5(f5); + }).catch((n5) => { + k5(n5); }); } } class AtomicServiceApi extends AtomicService { - constructor(y4, z4, a5) { - super(y4, z4, a5); + constructor(g5, h5, i5) { + super(g5, h5, i5); } - pushUrl(u4) { - if (!this.checkRouterMode(u4.mode, u4)) { + pushUrl(c5) { + if (!this.checkRouterMode(c5.mode, c5)) { return; } - router.pushUrl({ url: u4.url, params: u4.params }, this.parseRouterMode(u4.mode)).then(() => { - this.success(new PushUrlResult(), u4); - }).catch((x4) => { - this.error(x4, u4); + router.pushUrl({ url: c5.url, params: c5.params }, this.parseRouterMode(c5.mode)).then(() => { + this.success(new PushUrlResult(), c5); + }).catch((f5) => { + this.error(f5, c5); }); } - replaceUrl(q4) { - if (!this.checkRouterMode(q4.mode, q4)) { + replaceUrl(y4) { + if (!this.checkRouterMode(y4.mode, y4)) { return; } - router.replaceUrl({ url: q4.url, params: q4.params }, this.parseRouterMode(q4.mode)).then(() => { - this.success(new ReplaceUrlResult(), q4); - }).catch((t4) => { - this.error(t4, q4); + router.replaceUrl({ url: y4.url, params: y4.params }, this.parseRouterMode(y4.mode)).then(() => { + this.success(new ReplaceUrlResult(), y4); + }).catch((b5) => { + this.error(b5, y4); }); } - backUrl(p4) { - if (p4.url) { - if (!this.checkBackUrlExists(p4.url, p4)) { + backUrl(x4) { + if (x4.url) { + if (!this.checkBackUrlExists(x4.url, x4)) { return; } - router.back({ url: p4.url, params: p4.params }); - this.success(new BackUrlResult(), p4); - } else if (p4.index || p4.index === 0) { - if (!this.checkNumberParamPositive('index', p4.index, p4)) { + router.back({ url: x4.url, params: x4.params }); + this.success(new BackUrlResult(), x4); + } else if (x4.index || x4.index === 0) { + if (!this.checkNumberParamPositive('index', x4.index, x4)) { return; } - router.back(p4.index, p4.params); - this.success(new BackUrlResult(), p4); - } else if (p4.delta || p4.delta === 0) { - if (!this.checkNumberParamPositive('delta', p4.delta, p4)) { + router.back(x4.index, x4.params); + this.success(new BackUrlResult(), x4); + } else if (x4.delta || x4.delta === 0) { + if (!this.checkNumberParamPositive('delta', x4.delta, x4)) { return; } - router.back(this.getRouterIndexByDelta(p4.delta), p4.params); - this.success(new BackUrlResult(), p4); + router.back(this.getRouterIndexByDelta(x4.delta), x4.params); + this.success(new BackUrlResult(), x4); } else { router.back(); - this.success(new BackUrlResult(), p4); + this.success(new BackUrlResult(), x4); } } - clearUrl(o4) { + clearUrl(w4) { router.clear(); - this.success(new ClearUrlResult(), o4); + this.success(new ClearUrlResult(), w4); } - pushPath(m4) { - if (!this.checkNavPathStack('navPathStack.pushPath', m4)) { + pushPath(u4) { + if (!this.checkNavPathStack('navPathStack.pushPath', u4)) { return; } this.navPathStack?.pushPath({ - name: m4.name, - param: m4.param, - onPop: n4 => this.onPopHandler(n4, m4.onPop) - }, m4.animated); - this.success(new PushPathResult(), m4); + name: u4.name, + param: u4.param, + onPop: v4 => this.onPopHandler(v4, u4.onPop) + }, u4.animated); + this.success(new PushPathResult(), u4); } - replacePath(k4) { - if (!this.checkNavPathStack('navPathStack.replacePath', k4)) { + replacePath(s4) { + if (!this.checkNavPathStack('navPathStack.replacePath', s4)) { return; } this.navPathStack?.replacePath({ - name: k4.name, - param: k4.param, - onPop: l4 => this.onPopHandler(l4, k4.onPop) - }, k4.animated); - this.success(new ReplacePathResult(), k4); + name: s4.name, + param: s4.param, + onPop: t4 => this.onPopHandler(t4, s4.onPop) + }, s4.animated); + this.success(new ReplacePathResult(), s4); } - popPath(h4) { - if (!this.checkNavPathStack('navPathStack.pop', h4)) { + popPath(p4) { + if (!this.checkNavPathStack('navPathStack.pop', p4)) { return; } - if (h4.name) { - let j4 = this.navPathStack?.popToName(h4.name, h4.result, h4.animated); - if (j4 === undefined || j4 === -1) { - this.errorWithCodeAndMsg(POP_PATH_NAME_NOT_EXIST_ERROR, h4); + if (p4.name) { + let r4 = this.navPathStack?.popToName(p4.name, p4.result, p4.animated); + if (r4 === undefined || r4 === -1) { + this.errorWithCodeAndMsg(POP_PATH_NAME_NOT_EXIST_ERROR, p4); return; } - } else if (h4.index || h4.index === 0) { - if (h4.index < -1) { - this.errorWithCodeAndMsg(POP_PATH_PARAM_INDEX_INVALID_ERROR, h4); + } else if (p4.index || p4.index === 0) { + if (p4.index < -1) { + this.errorWithCodeAndMsg(POP_PATH_PARAM_INDEX_INVALID_ERROR, p4); return; } - if (h4.index > this.getCurrentNavPathInfo().index) { - this.errorWithCodeAndMsg(POP_PATH_INDEX_OUT_OF_RANGE_ERROR, h4); + if (p4.index > this.getCurrentNavPathInfo().index) { + this.errorWithCodeAndMsg(POP_PATH_INDEX_OUT_OF_RANGE_ERROR, p4); return; } - this.navPathStack?.popToIndex(h4.index, h4.result, h4.animated); - } else if (h4.delta || h4.delta === 0) { - if (!this.checkNumberParamPositive('delta', h4.delta, h4)) { + this.navPathStack?.popToIndex(p4.index, p4.result, p4.animated); + } else if (p4.delta || p4.delta === 0) { + if (!this.checkNumberParamPositive('delta', p4.delta, p4)) { return; } - this.navPathStack?.popToIndex(this.getNavPathIndexByDelta(h4.delta), h4.result, h4.animated); + this.navPathStack?.popToIndex(this.getNavPathIndexByDelta(p4.delta), p4.result, p4.animated); } else { - this.navPathStack?.pop(h4.result, h4.animated); + this.navPathStack?.pop(p4.result, p4.animated); } - let i4 = this.getCurrentNavPathInfo(); - this.success(new PopPathResult(i4.name, i4.index, i4.param), h4); + let q4 = this.getCurrentNavPathInfo(); + this.success(new PopPathResult(q4.name, q4.index, q4.param), p4); } - clearPath(g4) { - if (!this.checkNavPathStack('navPathStack.clear', g4)) { + clearPath(o4) { + if (!this.checkNavPathStack('navPathStack.clear', o4)) { return; } - this.navPathStack?.clear(g4.animated); - this.success(new ClearPathResult(), g4); + this.navPathStack?.clear(o4.animated); + this.success(new ClearPathResult(), o4); } - postMessage(c3) { - c3.data && this.messageDataList.push(c3.data); - this.success(new PostMessageResult(), c3); + postMessage(n4) { + n4.data && this.messageDataList.push(n4.data); + this.success(new PostMessageResult(), n4); } - getEnv(e4) { - let f4 = new GetEnvResult(); - f4.deviceType = deviceInfo.deviceType; - f4.brand = deviceInfo.brand; - f4.productModel = deviceInfo.productModel; - f4.osFullName = deviceInfo.osFullName; - this.success(f4, e4); + getEnv(l4) { + let m4 = new GetEnvResult(); + m4.deviceType = deviceInfo.deviceType; + m4.brand = deviceInfo.brand; + m4.productModel = deviceInfo.productModel; + m4.osFullName = deviceInfo.osFullName; + this.success(m4, l4); } - checkJsApi(a4) { - let b4 = new Map(); - a4.jsApiList?.forEach(d4 => { - b4[d4] = this.isJsApiEnable(ATOMIC_SERVICE_JS_API_MAP.get(d4)); + checkJsApi(h4) { + let i4 = new Map(); + h4.jsApiList?.forEach(k4 => { + i4[k4] = this.isJsApiEnable(ATOMIC_SERVICE_JS_API_MAP.get(k4)); }); - this.success(new CheckJsApiResult(b4), a4); - } - - pickCamera(v3) { - picker.pick(this.context, v3.mediaTypes, { - cameraPosition: v3.cameraPosition, - saveUri: v3.saveUri, - videoDuration: v3.videoDuration - }).then((z3) => { - this.success(new PickCameraResult(z3.resultCode, z3.resultUri, z3.mediaType), v3); - }).catch((y3) => { - this.error(y3, v3); + this.success(new CheckJsApiResult(i4), h4); + } + + pickCamera(c4) { + picker.pick(this.context, c4.mediaTypes, { + cameraPosition: c4.cameraPosition, + saveUri: c4.saveUri, + videoDuration: c4.videoDuration + }).then((g4) => { + this.success(new PickCameraResult(g4.resultCode, g4.resultUri, g4.mediaType), c4); + }).catch((f4) => { + this.error(f4, c4); }); } - selectPhoto(p3) { - let q3 = new photoAccessHelper.PhotoViewPicker(); - q3.select({ - MIMEType: p3.mimeType, - maxSelectNumber: p3.maxSelectNumber, - isPhotoTakingSupported: p3.isPhotoTakingSupported, - isEditSupported: p3.isEditSupported, - isSearchSupported: p3.isSearchSupported, + selectPhoto(w3) { + let x3 = new photoAccessHelper.PhotoViewPicker(); + x3.select({ + MIMEType: w3.mimeType, + maxSelectNumber: w3.maxSelectNumber, + isPhotoTakingSupported: w3.isPhotoTakingSupported, + isEditSupported: w3.isEditSupported, + isSearchSupported: w3.isSearchSupported, recommendationOptions: { - recommendationType: p3.recommendationType + recommendationType: w3.recommendationType }, - preselectedUris: p3.preselectedUris - }).then((u3) => { - this.success(new SelectPhotoResult(u3.photoUris, u3.isOriginalPhoto), p3); - }).catch((t3) => { - this.error(t3, p3); + preselectedUris: w3.preselectedUris + }).then((b4) => { + this.success(new SelectPhotoResult(b4.photoUris, b4.isOriginalPhoto), w3); + }).catch((a4) => { + this.error(a4, w3); }); } - openPreview(g3) { - let h3 = this.getUri(g3.uri); - filePreview.canPreview(this.context, h3).then((l3) => { - if (!l3) { - this.errorWithCodeAndMsg(IMAGE_CAN_NOT_PREVIEW_ERROR, g3); + openPreview(n3) { + let o3 = this.getUri(n3.uri); + filePreview.canPreview(this.context, o3).then((s3) => { + if (!s3) { + this.errorWithCodeAndMsg(IMAGE_CAN_NOT_PREVIEW_ERROR, n3); return; } filePreview.openPreview(this.context, { - uri: h3, - mimeType: g3.mimeType, - title: g3.title + uri: o3, + mimeType: n3.mimeType, + title: n3.title }).then(() => { - this.success(new OpenPreviewResult(), g3); - }).catch((o3) => { - this.error(o3, g3); + this.success(new OpenPreviewResult(), n3); + }).catch((v3) => { + this.error(v3, n3); }); - }).catch((k3) => { - this.error(k3, g3); + }).catch((r3) => { + this.error(r3, n3); }); } - uploadFile(s2) { - this.checkUploadFile(s2).then(w2 => { - if (!w2.checkResult) { + uploadFile(z2) { + this.checkUploadFile(z2).then(d3 => { + if (!d3.checkResult) { return; } - let x2 = { - url: s2.url, - header: s2.header, - method: s2.method, - files: this.convertToFile(s2.files), - data: this.convertToRequestData(s2.data) + let e3 = { + url: z2.url, + header: z2.header, + method: z2.method, + files: this.convertToFile(z2.files), + data: this.convertToRequestData(z2.data) }; - this.consoleLog('uploadFile uploadConfig=' + JSON.stringify(x2)); - request.uploadFile(this.context, x2).then((b3) => { - b3.on('complete', (f3) => { - this.handleUploadFileResult(f3, w2.uriMap, s2); + this.consoleLog('uploadFile uploadConfig=' + JSON.stringify(e3)); + request.uploadFile(this.context, e3).then((i3) => { + i3.on('complete', (m3) => { + this.handleUploadFileResult(m3, d3.uriMap, z2); }); - b3.on('fail', (e3) => { - this.handleUploadFileResult(e3, w2.uriMap, s2); + i3.on('fail', (l3) => { + this.handleUploadFileResult(l3, d3.uriMap, z2); }); - }).catch((a3) => { - this.error(a3, s2); + }).catch((h3) => { + this.error(h3, z2); }); - }).catch((v2) => { - this.error(v2, s2); + }).catch((c3) => { + this.error(c3, z2); }); } - downloadFile(f2) { - let g2 = f2.fileName ? f2.fileName : this.parseFileNameFromUrl(f2.url); - let h2 = `${util.generateRandomUUID().replaceAll('-', '')}`; - let i2 = `${this.context.cacheDir}/${h2}`; + downloadFile(m2) { + let n2 = m2.fileName ? m2.fileName : this.parseFileNameFromUrl(m2.url); + let o2 = `${util.generateRandomUUID().replaceAll('-', '')}`; + let p2 = `${this.context.cacheDir}/${o2}`; request.downloadFile(this.context, { - url: f2.url, - header: f2.header ? f2.header : new Object(), - filePath: i2, - enableMetered: f2.enableMetered, - enableRoaming: f2.enableRoaming, - networkType: f2.networkType, + url: m2.url, + header: m2.header ? m2.header : new Object(), + filePath: p2, + enableMetered: m2.enableMetered, + enableRoaming: m2.enableRoaming, + networkType: m2.networkType, background: false - }).then((m2) => { - m2.on('complete', () => { - this.saveDownloadFile(i2, g2, f2, r2 => { - this.success(new DownloadFileResult(r2), f2); + }).then((t2) => { + t2.on('complete', () => { + this.saveDownloadFile(p2, n2, m2, y2 => { + this.success(new DownloadFileResult(y2), m2); }); }); - m2.on('fail', y2 => { - this.errorWithCodeAndMsg(new Error(y2, 'File download fail.'), f2); + t2.on('fail', w2 => { + this.errorWithCodeAndMsg(new AsError(w2, 'File download fail.'), m2); }); - }).catch((l2) => { - this.error(l2, f2); + }).catch((s2) => { + this.error(s2, m2); }); } - getNetworkType(v1) { - connection.getDefaultNet().then(z1 => { - if (!z1 || z1.netId === 0) { - this.errorWithCodeAndMsg(NETWORK_NO_ACTIVE_ERROR, v1); + getNetworkType(c2) { + connection.getDefaultNet().then(g2 => { + if (!g2 || g2.netId === 0) { + this.errorWithCodeAndMsg(NETWORK_NO_ACTIVE_ERROR, c2); return; } - connection.getNetCapabilities(z1).then(n2 => { - let t2 = new GetNetworkTypeResult(n2.bearerTypes, n2.networkCap, n2.linkUpBandwidthKbps, - n2.linkDownBandwidthKbps); - this.success(t2, v1); + connection.getNetCapabilities(g2).then(k2 => { + let l2 = new GetNetworkTypeResult(k2.bearerTypes, k2.networkCap, k2.linkUpBandwidthKbps, + k2.linkDownBandwidthKbps); + this.success(l2, c2); }).catch((j2) => { - this.error(j2, v1); + this.error(j2, c2); }); - }).catch((y1) => { - this.error(y1, v1); + }).catch((f2) => { + this.error(f2, c2); }); } - getLocation(n1) { - this.checkPermissions(PERMISSION_APPROXIMATELY_LOCATION, p1 => { - if (p1) { - this.error(p1, n1); + getLocation(u1) { + this.checkPermissions(PERMISSION_APPROXIMATELY_LOCATION, w1 => { + if (w1) { + this.error(w1, u1); return; } geoLocationManager.getCurrentLocation({ - priority: n1.priority, - scenario: n1.scenario, - maxAccuracy: n1.maxAccuracy, - timeoutMs: n1.timeoutMs - }).then(t1 => { - let u1 = - new GetLocationResult(t1.latitude, t1.longitude, t1.altitude, t1.accuracy, t1.speed, t1.timeStamp, - t1.direction, t1.timeSinceBoot, t1.additions, t1.additionSize); - this.success(u1, n1); - }).catch((s1) => { - this.error(s1, n1); + priority: u1.priority, + scenario: u1.scenario, + maxAccuracy: u1.maxAccuracy, + timeoutMs: u1.timeoutMs + }).then(a2 => { + let b2 = + new GetLocationResult(a2.latitude, a2.longitude, a2.altitude, a2.accuracy, a2.speed, a2.timeStamp, + a2.direction, a2.timeSinceBoot, a2.additions, a2.additionSize); + this.success(b2, u1); + }).catch((z1) => { + this.error(z1, u1); }); }); } } class NavPathInfo { - constructor(l1, m1) { - this.name = l1; - this.index = m1; + constructor(s1, t1) { + this.name = s1; + this.index = t1; } } class CheckUploadFileResult { - constructor(j1, k1) { - this.checkResult = j1; - this.uriMap = k1; + constructor(q1, r1) { + this.checkResult = q1; + this.uriMap = r1; } } @@ -948,10 +948,10 @@ class ClearUrlResult { } class OnPopEvent { - constructor(g1, h1, i1) { - this.name = g1; - this.param = h1; - this.result = i1; + constructor(n1, o1, p1) { + this.name = n1; + this.param = o1; + this.result = p1; } } @@ -971,10 +971,10 @@ class PopPathOptions extends BaseOptions { } class PopPathResult { - constructor(d1, e1, f1) { - this.name = d1; - this.index = e1; - this.param = f1; + constructor(k1, l1, m1) { + this.name = k1; + this.index = l1; + this.param = m1; } } @@ -991,34 +991,34 @@ class PostMessageResult { } export class OnMessageEvent { - constructor(c2) { - this.data = c2; + constructor(j1) { + this.data = j1; } } export class OnErrorReceiveEvent { - constructor(r4, v4) { - this.request = r4; - this.error = v4; + constructor(h1, i1) { + this.request = h1; + this.error = i1; } } export class OnHttpErrorReceiveEvent { - constructor(r3, w3) { - this.request = r3; - this.response = w3; + constructor(f1, g1) { + this.request = f1; + this.response = g1; } } export class OnPageBeginEvent { - constructor(e2) { - this.url = e2; + constructor(e1) { + this.url = e1; } } export class OnPageEndEvent { - constructor(d2) { - this.url = d2; + constructor(d1) { + this.url = d1; } } diff --git a/advanced_ui_component/atomicserviceweb/source/atomicserviceweb.ets b/advanced_ui_component/atomicserviceweb/source/atomicserviceweb.ets index 15048be67ee..d5a4d303de8 100644 --- a/advanced_ui_component/atomicserviceweb/source/atomicserviceweb.ets +++ b/advanced_ui_component/atomicserviceweb/source/atomicserviceweb.ets @@ -31,7 +31,7 @@ import picker from '@ohos.multimedia.cameraPicker'; import filePicker from '@ohos.file.picker'; import { BusinessError } from '@ohos.base'; -class Error { +class AsError { public code: number; public message: string; @@ -69,43 +69,41 @@ const MAX_VERSION = '99.99.99'; const ATOMIC_SERVICE_JS_SDK_CURRENT_VERSION = '1.0.0'; const PERMISSION_APPROXIMATELY_LOCATION: Permissions = 'ohos.permission.APPROXIMATELY_LOCATION'; -const SYSTEM_INTERNAL_ERROR: Error = new Error(500, 'System internal error.'); -const JS_API_INVALID_INVOKE_ERROR: Error = new Error(200001, 'Invalid invoke.'); +const SYSTEM_INTERNAL_ERROR: AsError = new AsError(500, 'System internal error.'); +const JS_API_INVALID_INVOKE_ERROR: AsError = new AsError(200001, 'Invalid invoke.'); const PARAM_REQUIRED_ERROR_CODE: number = 200002; const PARAM_NUMBER_POSITIVE_ERROR_CODE: number = 200003; -const ROUTER_PARAM_MODE_INVALID_ERROR: Error = new Error(200004, 'Param mode is invalid.'); -const BACK_URL_NOT_EXIST_OR_OPENED_ERROR: Error = new Error(200005, 'Url is not exist or opened, can not be back.'); +const ROUTER_PARAM_MODE_INVALID_ERROR: AsError = new AsError(200004, 'Param mode is invalid.'); +const BACK_URL_NOT_EXIST_OR_OPENED_ERROR: AsError = new AsError(200005, 'Url is not exist or opened, can not be back.'); const NAV_PATH_STACK_NOT_EXIST_ERROR_CODE: number = 200006; -const POP_PATH_NAME_NOT_EXIST_ERROR: Error = new Error(200007, 'Name is not exist or opened, can not be pop.'); -const POP_PATH_PARAM_INDEX_INVALID_ERROR: Error = new Error(200008, 'Param index is invalid.'); -const POP_PATH_INDEX_OUT_OF_RANGE_ERROR: Error = new Error(200009, 'The Index is out of range.'); -const UPLOAD_IMAGE_FILES_REQUIRED_ERROR: Error = new Error(200010, 'Param files is required.'); +const POP_PATH_NAME_NOT_EXIST_ERROR: AsError = new AsError(200007, 'Name is not exist or opened, can not be pop.'); +const POP_PATH_PARAM_INDEX_INVALID_ERROR: AsError = new AsError(200008, 'Param index is invalid.'); +const POP_PATH_INDEX_OUT_OF_RANGE_ERROR: AsError = new AsError(200009, 'The Index is out of range.'); +const UPLOAD_IMAGE_FILES_REQUIRED_ERROR: AsError = new AsError(200010, 'Param files is required.'); const UPLOAD_IMAGE_FILE_NOT_EXIST_ERROR_CODE: number = 200011; -const UPLOAD_IMAGE_FILES_URI_REQUIRED_ERROR: Error = new Error(200012, 'Param uri of files is required.'); -const UPLOAD_FILE_ERROR: Error = new Error(200013, 'Upload file error.'); -const IMAGE_CAN_NOT_PREVIEW_ERROR: Error = new Error(200014, 'The filePath can not preview.'); -const NETWORK_NO_ACTIVE_ERROR: Error = new Error(200015, 'The network is not active.'); - -{ - registerJsApi('router.pushUrl', 'pushUrl', '1.0.0', MAX_VERSION, ['url']); - registerJsApi('router.replaceUrl', 'replaceUrl', '1.0.0', MAX_VERSION, ['url']); - registerJsApi('router.back', 'backUrl', '1.0.0', MAX_VERSION, []); - registerJsApi('router.clear', 'clearUrl', '1.0.0', MAX_VERSION, []); - registerJsApi('navPathStack.pushPath', 'pushPath', '1.0.0', MAX_VERSION, ['name']); - registerJsApi('navPathStack.replacePath', 'replacePath', '1.0.0', MAX_VERSION, ['name']); - registerJsApi('navPathStack.pop', 'popPath', '1.0.0', MAX_VERSION, []); - registerJsApi('navPathStack.clear', 'clearPath', '1.0.0', MAX_VERSION, []); - registerJsApi('asWeb.postMessage', 'postMessage', '1.0.0', MAX_VERSION, ['data']); - registerJsApi('asWeb.getEnv', 'getEnv', '1.0.0', MAX_VERSION, []); - registerJsApi('asWeb.checkJsApi', 'checkJsApi', '1.0.0', MAX_VERSION, ['jsApiList']); - registerJsApi('cameraPicker.pick', 'pickCamera', '1.0.0', MAX_VERSION, ['mediaTypes', 'cameraPosition']); - registerJsApi('photoViewPicker.select', 'selectPhoto', '1.0.0', MAX_VERSION, []); - registerJsApi('filePreview.openPreview', 'openPreview', '1.0.0', MAX_VERSION, ['uri']); - registerJsApi('request.uploadFile', 'uploadFile', '1.0.0', MAX_VERSION, ['url', 'files']); - registerJsApi('request.downloadFile', 'downloadFile', '1.0.0', MAX_VERSION, ['url']); - registerJsApi('connection.getNetworkType', 'getNetworkType', '1.0.0', MAX_VERSION, []); - registerJsApi('location.getLocation', 'getLocation', '1.0.0', MAX_VERSION, []); -} +const UPLOAD_IMAGE_FILES_URI_REQUIRED_ERROR: AsError = new AsError(200012, 'Param uri of files is required.'); +const UPLOAD_FILE_ERROR: AsError = new AsError(200013, 'Upload file error.'); +const IMAGE_CAN_NOT_PREVIEW_ERROR: AsError = new AsError(200014, 'The filePath can not preview.'); +const NETWORK_NO_ACTIVE_ERROR: AsError = new AsError(200015, 'The network is not active.'); + +registerJsApi('router.pushUrl', 'pushUrl', '1.0.0', MAX_VERSION, ['url']); +registerJsApi('router.replaceUrl', 'replaceUrl', '1.0.0', MAX_VERSION, ['url']); +registerJsApi('router.back', 'backUrl', '1.0.0', MAX_VERSION, []); +registerJsApi('router.clear', 'clearUrl', '1.0.0', MAX_VERSION, []); +registerJsApi('navPathStack.pushPath', 'pushPath', '1.0.0', MAX_VERSION, ['name']); +registerJsApi('navPathStack.replacePath', 'replacePath', '1.0.0', MAX_VERSION, ['name']); +registerJsApi('navPathStack.pop', 'popPath', '1.0.0', MAX_VERSION, []); +registerJsApi('navPathStack.clear', 'clearPath', '1.0.0', MAX_VERSION, []); +registerJsApi('asWeb.postMessage', 'postMessage', '1.0.0', MAX_VERSION, ['data']); +registerJsApi('asWeb.getEnv', 'getEnv', '1.0.0', MAX_VERSION, []); +registerJsApi('asWeb.checkJsApi', 'checkJsApi', '1.0.0', MAX_VERSION, ['jsApiList']); +registerJsApi('cameraPicker.pick', 'pickCamera', '1.0.0', MAX_VERSION, ['mediaTypes', 'cameraPosition']); +registerJsApi('photoViewPicker.select', 'selectPhoto', '1.0.0', MAX_VERSION, []); +registerJsApi('filePreview.openPreview', 'openPreview', '1.0.0', MAX_VERSION, ['uri']); +registerJsApi('request.uploadFile', 'uploadFile', '1.0.0', MAX_VERSION, ['url', 'files']); +registerJsApi('request.downloadFile', 'downloadFile', '1.0.0', MAX_VERSION, ['url']); +registerJsApi('connection.getNetworkType', 'getNetworkType', '1.0.0', MAX_VERSION, []); +registerJsApi('location.getLocation', 'getLocation', '1.0.0', MAX_VERSION, []); @Component export struct AtomicServiceWeb { @@ -121,7 +119,7 @@ export struct AtomicServiceWeb { }; public onPageEnd?: Callback = () => { }; - private context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext; + private context: common.UIAbilityContext = this.getUIContext().getHostContext() as common.UIAbilityContext; private controller: web_webview.WebviewController = new web_webview.WebviewController(); private schemeHandler: web_webview.WebSchemeHandler = new web_webview.WebSchemeHandler(); private atomicService?: AtomicService; @@ -242,11 +240,11 @@ class AtomicService { } error(err: BusinessError, options: BaseOptions,): void { - options?.callback && options?.callback(new Error(err.code ? err.code : SYSTEM_INTERNAL_ERROR.code, + options?.callback && options?.callback(new AsError(err.code ? err.code : SYSTEM_INTERNAL_ERROR.code, err.message ? err.message : SYSTEM_INTERNAL_ERROR.message)); } - errorWithCodeAndMsg(error: Error, options: BaseOptions): void { + errorWithCodeAndMsg(error: AsError, options: BaseOptions): void { options?.callback && options?.callback(error); } @@ -268,7 +266,7 @@ class AtomicService { checkParamRequired(paramKey: string, paramValue: V, options: BaseOptions): boolean { if (paramValue === undefined || paramValue === null || paramValue === '') { - this.errorWithCodeAndMsg(new Error(PARAM_REQUIRED_ERROR_CODE, `Param ${paramKey} is required.`), options); + this.errorWithCodeAndMsg(new AsError(PARAM_REQUIRED_ERROR_CODE, `Param ${paramKey} is required.`), options); return false; } return true; @@ -276,7 +274,7 @@ class AtomicService { checkNumberParamPositive(paramKey: string, paramValue: number, options: BaseOptions): boolean { if (paramValue <= 0) { - this.errorWithCodeAndMsg(new Error(PARAM_NUMBER_POSITIVE_ERROR_CODE, + this.errorWithCodeAndMsg(new AsError(PARAM_NUMBER_POSITIVE_ERROR_CODE, `Param ${paramKey} must be a positive number.`), options); return false; } @@ -313,7 +311,7 @@ class AtomicService { } getRouterIndexByDelta(delta: number): number { - let length: number = parseInt(router.getLength()); + let length: number = Number.parseInt(router.getLength()); for (let i = length; i > 0; i--) { let state = router.getStateByIndex(i); if (state?.name && delta-- == 0) { @@ -324,7 +322,7 @@ class AtomicService { } checkBackUrlExists(url: string, options: BaseOptions): boolean { - let length: number = parseInt(router.getLength()); + let length: number = Number.parseInt(router.getLength()); for (let i = length; i > 0; i--) { let state = router.getStateByIndex(i); if (state?.name) { @@ -340,7 +338,7 @@ class AtomicService { checkNavPathStack(apiName: string, options: BaseOptions): boolean { if (!this.navPathStack) { - this.errorWithCodeAndMsg(new Error(NAV_PATH_STACK_NOT_EXIST_ERROR_CODE, + this.errorWithCodeAndMsg(new AsError(NAV_PATH_STACK_NOT_EXIST_ERROR_CODE, `Current page is not NavDestination, not support ${apiName}().`), options); return false; } @@ -395,9 +393,10 @@ class AtomicService { if (!lowVersion || !highVersion) { return false; } - let v1 = lowVersion.split('.').map(m => parseInt(m)); - let v2 = highVersion.split('.').map(m => parseInt(m)); - for (let i = 0; i < v1.length && i < v2.length; i++) { + let v1 = lowVersion.split('.').map(m => Number.parseInt(m)); + let v2 = highVersion.split('.').map(m => Number.parseInt(m)); + const maxLength = Math.max(v1.length, v2.length); + for (let i = 0; i < maxLength; i++) { if (v1[i] < v2[i]) { return true; } else if (v1[i] > v2[i]) { @@ -433,7 +432,7 @@ class AtomicService { return new CheckUploadFileResult(false); } if (!file.uri.startsWith('file://') && !fs.accessSync(file.uri, fs.AccessModeType.EXIST)) { - this.errorWithCodeAndMsg(new Error(UPLOAD_IMAGE_FILE_NOT_EXIST_ERROR_CODE, + this.errorWithCodeAndMsg(new AsError(UPLOAD_IMAGE_FILE_NOT_EXIST_ERROR_CODE, `File uri ${file.uri} is not exist.`), options); return new CheckUploadFileResult(false); } @@ -806,7 +805,7 @@ class AtomicServiceApi extends AtomicService { }); }); downloadTask.on('fail', errCode => { - this.errorWithCodeAndMsg(new Error(errCode, 'File download fail.'), options); + this.errorWithCodeAndMsg(new AsError(errCode, 'File download fail.'), options); }); }).catch((err: BusinessError) => { this.error(err, options); @@ -876,7 +875,7 @@ class CheckUploadFileResult { } class BaseOptions { - public callback?: (err: Error | undefined, res?: T) => void; + public callback?: (err: AsError | undefined, res?: T) => void; } class PushUrlOptions extends BaseOptions { -- Gitee