已合并
新增支持传入窗口参数拉起加密保护页面功能 #907
0202zc创建于 11 天前
新增支持传入窗口参数拉起加密保护页面功能 #907
已合并
共 7 个文件变更+606-292
| @@ -1,4 +1,4 @@ | |||
| 1 | -# Copyright (c) 2023 Huawei Device Co., Ltd. | 1 | +# Copyright (c) 2023-2026 Huawei Device Co., Ltd. |
| 2 | # Licensed under the Apache License, Version 2.0 (the "License"); | 2 | # Licensed under the Apache License, Version 2.0 (the "License"); |
| 3 | # you may not use this file except in compliance with the License. | 3 | # you may not use this file except in compliance with the License. |
| 4 | # You may obtain a copy of the License at | 4 | # You may obtain a copy of the License at |
| @@ -48,11 +48,13 @@ ohos_shared_library("libdlppermission_napi") { | |||
| 48 | "${dlp_root_dir}/interfaces/kits/dlp_permission/napi/src/napi_dlp_permission.cpp", | 48 | "${dlp_root_dir}/interfaces/kits/dlp_permission/napi/src/napi_dlp_permission.cpp", |
| 49 | "${dlp_root_dir}/interfaces/kits/dlp_permission/napi/src/napi_dlp_permission_enterprise.cpp", | 49 | "${dlp_root_dir}/interfaces/kits/dlp_permission/napi/src/napi_dlp_permission_enterprise.cpp", |
| 50 | "${dlp_root_dir}/interfaces/kits/dlp_permission/napi/src/napi_dlp_permission_manager.cpp", | 50 | "${dlp_root_dir}/interfaces/kits/dlp_permission/napi/src/napi_dlp_permission_manager.cpp", |
| 51 | + "${dlp_root_dir}/interfaces/kits/dlp_permission/napi/src/napi_dlp_permission_ui_extension.cpp", | ||
| 51 | "${dlp_root_dir}/interfaces/kits/dlp_permission/napi/src/napi_dlp_connection_plugin.cpp", | 52 | "${dlp_root_dir}/interfaces/kits/dlp_permission/napi/src/napi_dlp_connection_plugin.cpp", |
| 52 | "${dlp_root_dir}/interfaces/kits/dlp_permission/napi/src/napi_dlp_transparent_enc.cpp", | 53 | "${dlp_root_dir}/interfaces/kits/dlp_permission/napi/src/napi_dlp_transparent_enc.cpp", |
| 53 | "${dlp_root_dir}/interfaces/kits/napi_common/src/napi_common.cpp", | 54 | "${dlp_root_dir}/interfaces/kits/napi_common/src/napi_common.cpp", |
| 54 | "${dlp_root_dir}/interfaces/kits/napi_common/src/napi_common_custom.cpp", | 55 | "${dlp_root_dir}/interfaces/kits/napi_common/src/napi_common_custom.cpp", |
| 55 | "${dlp_root_dir}/interfaces/kits/napi_common/src/napi_common_enterprise.cpp", | 56 | "${dlp_root_dir}/interfaces/kits/napi_common/src/napi_common_enterprise.cpp", |
| 57 | + "${dlp_root_dir}/interfaces/kits/napi_common/src/napi_common_ui_extension.cpp", | ||
| 56 | "${dlp_root_dir}/interfaces/kits/napi_common/src/napi_error_msg.cpp", | 58 | "${dlp_root_dir}/interfaces/kits/napi_common/src/napi_error_msg.cpp", |
| 57 | ] | 59 | ] |
| 58 | 60 | ||
| @@ -157,6 +159,7 @@ ohos_shared_library("libdlpsetdlpfeature_napi") { | |||
| 157 | "${dlp_root_dir}/interfaces/kits/napi_common/src/napi_common.cpp", | 159 | "${dlp_root_dir}/interfaces/kits/napi_common/src/napi_common.cpp", |
| 158 | "${dlp_root_dir}/interfaces/kits/napi_common/src/napi_common_custom.cpp", | 160 | "${dlp_root_dir}/interfaces/kits/napi_common/src/napi_common_custom.cpp", |
| 159 | "${dlp_root_dir}/interfaces/kits/napi_common/src/napi_common_enterprise.cpp", | 161 | "${dlp_root_dir}/interfaces/kits/napi_common/src/napi_common_enterprise.cpp", |
| 162 | + "${dlp_root_dir}/interfaces/kits/napi_common/src/napi_common_ui_extension.cpp", | ||
| 160 | "${dlp_root_dir}/interfaces/kits/napi_common/src/napi_error_msg.cpp", | 163 | "${dlp_root_dir}/interfaces/kits/napi_common/src/napi_error_msg.cpp", |
| 161 | ] | 164 | ] |
| 162 | 165 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | - * Copyright (c) 2023-2024 Huawei Device Co., Ltd. | 2 | + * Copyright (c) 2023-2026 Huawei Device Co., Ltd. |
| 3 | * Licensed under the Apache License, Version 2.0 (the "License"); | 3 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | * you may not use this file except in compliance with the License. | 4 | * you may not use this file except in compliance with the License. |
| 5 | * You may obtain a copy of the License at | 5 | * You may obtain a copy of the License at |
| @@ -142,6 +142,8 @@ private: | |||
| 142 | static void GetSandboxAppConfigComplete(napi_env env, napi_status status, void* data); | 142 | static void GetSandboxAppConfigComplete(napi_env env, napi_status status, void* data); |
| 143 | static napi_value GetSandboxAppConfig(napi_env env, napi_callback_info cbInfo); | 143 | static napi_value GetSandboxAppConfig(napi_env env, napi_callback_info cbInfo); |
| 144 | 144 | ||
| 145 | + static bool ParseStartDLPManagerParams(napi_env env, napi_callback_info cbInfo, | ||
| 146 | + size_t &argc, napi_value *argv, napi_value &result); | ||
| 145 | static napi_value StartDLPManagerForResult(napi_env env, napi_callback_info cbInfo); | 147 | static napi_value StartDLPManagerForResult(napi_env env, napi_callback_info cbInfo); |
| 146 | 148 | ||
| 147 | static napi_value IsDLPFeatureProvided(napi_env env, napi_callback_info cbInfo); | 149 | static napi_value IsDLPFeatureProvided(napi_env env, napi_callback_info cbInfo); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | - * Copyright (c) 2023-2025 Huawei Device Co., Ltd. | 2 | + * Copyright (c) 2023-2026 Huawei Device Co., Ltd. |
| 3 | * Licensed under the Apache License, Version 2.0 (the "License"); | 3 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | * you may not use this file except in compliance with the License. | 4 | * you may not use this file except in compliance with the License. |
| 5 | * You may obtain a copy of the License at | 5 | * You may obtain a copy of the License at |
| @@ -2039,47 +2039,6 @@ bool NapiDlpPermission::IsSystemApp(napi_env env) | |||
| 2039 | return true; | 2039 | return true; |
| 2040 | } | 2040 | } |
| 2041 | 2041 | ||
| 2042 | -napi_value NapiDlpPermission::StartDLPManagerForResult(napi_env env, napi_callback_info cbInfo) | ||
| 2043 | -{ | ||
| 2044 | - if (CheckDevice(env)) { | ||
| 2045 | - return nullptr; | ||
| 2046 | - } | ||
| 2047 | - DLP_LOG_INFO(LABEL, "begin StartDLPManagerForResult"); | ||
| 2048 | - size_t argc = PARAM_SIZE_TWO; | ||
| 2049 | - size_t maxArgcNum = PARAM_SIZE_TWO; | ||
| 2050 | - size_t contextIndex = PARAM0; | ||
| 2051 | - size_t requestIndex = PARAM1; | ||
| 2052 | - | ||
| 2053 | - napi_value argv[PARAM2] = {nullptr}; | ||
| 2054 | - napi_value thisVar = nullptr; | ||
| 2055 | - napi_value result = nullptr; | ||
| 2056 | - NAPI_CALL(env, napi_get_undefined(env, &result)); | ||
| 2057 | - NAPI_CALL(env, napi_get_cb_info(env, cbInfo, &argc, argv, &thisVar, nullptr)); | ||
| 2058 | - if (argc != maxArgcNum) { | ||
| 2059 | - DLP_LOG_ERROR(LABEL, "params number mismatch"); | ||
| 2060 | - std::string errMsg = "Parameter Error. Params number mismatch, need " + std::to_string(maxArgcNum) + | ||
| 2061 | - ", given " + std::to_string(argc); | ||
| 2062 | - DlpNapiThrow(env, ERR_JS_PARAMETER_ERROR, errMsg); | ||
| 2063 | - return result; | ||
| 2064 | - } | ||
| 2065 | - | ||
| 2066 | - auto asyncContext = std::make_shared<UIExtensionRequestContext>(env); | ||
| 2067 | - if (!ParseUIAbilityContextReq(env, argv[contextIndex], asyncContext->context)) { | ||
| 2068 | - DLP_LOG_ERROR(LABEL, "ParseUIAbilityContextReq failed"); | ||
| 2069 | - DlpNapiThrow(env, ERR_JS_INVALID_PARAMETER, "get context failed"); | ||
| 2070 | - return result; | ||
| 2071 | - } | ||
| 2072 | - if (!ParseWantReq(env, argv[requestIndex], asyncContext->requestWant)) { | ||
| 2073 | - DLP_LOG_ERROR(LABEL, "ParseWantReq failed"); | ||
| 2074 | - return result; | ||
| 2075 | - } | ||
| 2076 | - NAPI_CALL(env, napi_create_promise(env, &asyncContext->deferred, &result)); | ||
| 2077 | - | ||
| 2078 | - StartUIExtensionAbility(asyncContext); | ||
| 2079 | - DLP_LOG_DEBUG(LABEL, "end StartDLPManagerForResult"); | ||
| 2080 | - return result; | ||
| 2081 | -} | ||
| 2082 | - | ||
| 2083 | void NapiDlpPermission::InitFunction(napi_env env, napi_value exports) | 2042 | void NapiDlpPermission::InitFunction(napi_env env, napi_value exports) |
| 2084 | { | 2043 | { |
| 2085 | napi_property_descriptor desc[] = { | 2044 | napi_property_descriptor desc[] = { |
| @@ -0,0 +1,104 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (c) 2026 Huawei Device Co., Ltd. | ||
| 3 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | + * you may not use this file except in compliance with the License. | ||
| 5 | + * You may obtain a copy of the License at | ||
| 6 | + * | ||
| 7 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | + * | ||
| 9 | + * Unless required by applicable law or agreed to in writing, software | ||
| 10 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | + * See the License for the specific language governing permissions and | ||
| 13 | + * limitations under the License. | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | +namespace OHOS { | ||
| 26 | +namespace Security { | ||
| 27 | +namespace DlpPermission { | ||
| 28 | +namespace { | ||
| 29 | +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_DLP_PERMISSION, "DlpPermissionNapi"}; | ||
| 30 | +} // namespace | ||
| 31 | + | ||
| 32 | +bool NapiDlpPermission::ParseStartDLPManagerParams(napi_env env, napi_callback_info cbInfo, | ||
| 33 | + size_t &argc, napi_value *argv, napi_value &result) | ||
| 34 | +{ | ||
| 35 | + argc = PARAM_SIZE_THREE; | ||
| 36 | + napi_value thisVar = nullptr; | ||
| 37 | + NAPI_CALL_BASE(env, napi_get_undefined(env, &result), false); | ||
| 38 | + NAPI_CALL_BASE(env, napi_get_cb_info(env, cbInfo, &argc, argv, &thisVar, nullptr), false); | ||
| 39 | + if (argc != PARAM_SIZE_TWO && argc != PARAM_SIZE_THREE) { | ||
| 40 | + DLP_LOG_ERROR(LABEL, "params number mismatch"); | ||
| 41 | + return false; | ||
| 42 | + } | ||
| 43 | + return true; | ||
| 44 | +} | ||
| 45 | + | ||
| 46 | +napi_value NapiDlpPermission::StartDLPManagerForResult(napi_env env, napi_callback_info cbInfo) | ||
| 47 | +{ | ||
| 48 | + if (CheckDevice(env)) { | ||
| 49 | + return nullptr; | ||
| 50 | + } | ||
| 51 | + DLP_LOG_INFO(LABEL, "begin StartDLPManagerForResult"); | ||
| 52 | + size_t argc = 0; | ||
| 53 | + napi_value argv[PARAM3] = {nullptr}; | ||
| 54 | + napi_value result = nullptr; | ||
| 55 | + if (!ParseStartDLPManagerParams(env, cbInfo, argc, argv, result)) { | ||
| 56 | + std::string errMsg = "Parameter Error. Params number mismatch, need 2 or 3, given " + | ||
| 57 | + std::to_string(argc); | ||
| 58 | + DlpNapiThrow(env, ERR_JS_PARAMETER_ERROR, errMsg); | ||
| 59 | + return nullptr; | ||
| 60 | + } | ||
| 61 | + | ||
| 62 | + auto asyncContext = std::make_shared<UIExtensionRequestContext>(env); | ||
| 63 | + if (argc == PARAM_SIZE_THREE) { | ||
| 64 | + // 3-param overload: context(common.Context), want, window | ||
| 65 | + // context only needs basic object validation, UIContent comes from window | ||
| 66 | + if (!ParseContextReq(env, argv[PARAM0], asyncContext->context)) { | ||
| 67 | + DLP_LOG_ERROR(LABEL, "ParseContextReq failed"); | ||
| 68 | + DlpNapiThrow(env, ERR_JS_INVALID_PARAMETER, "get context failed"); | ||
| 69 | + return nullptr; | ||
| 70 | + } | ||
| 71 | + } else { | ||
| 72 | + // 2-param overload: context(common.UIAbilityContext), want | ||
| 73 | + if (!ParseUIAbilityContextReq(env, argv[PARAM0], asyncContext->context)) { | ||
| 74 | + DLP_LOG_ERROR(LABEL, "ParseUIAbilityContextReq failed"); | ||
| 75 | + DlpNapiThrow(env, ERR_JS_INVALID_PARAMETER, "get context failed"); | ||
| 76 | + return nullptr; | ||
| 77 | + } | ||
| 78 | + } | ||
| 79 | + if (!ParseWantReq(env, argv[PARAM1], asyncContext->requestWant)) { | ||
| 80 | + DLP_LOG_ERROR(LABEL, "ParseWantReq failed"); | ||
| 81 | + return nullptr; | ||
| 82 | + } | ||
| 83 | + | ||
| 84 | + if (argc == PARAM_SIZE_THREE) { | ||
| 85 | + // 3-param overload: context(common.Context), want, window | ||
| 86 | + if (!GetCustomShowingWindow(env, argv[PARAM2], asyncContext->window)) { | ||
| 87 | + DLP_LOG_ERROR(LABEL, "GetCustomShowingWindow failed"); | ||
| 88 | + DlpNapiThrow(env, ERR_JS_INVALID_PARAMETER, "get window failed"); | ||
| 89 | + return nullptr; | ||
| 90 | + } | ||
| 91 | + NAPI_CALL(env, napi_create_promise(env, &asyncContext->deferred, &result)); | ||
| 92 | + StartUIExtensionAbilityWithWindow(asyncContext); | ||
| 93 | + } else { | ||
| 94 | + // 2-param overload: context(common.UIAbilityContext), want | ||
| 95 | + NAPI_CALL(env, napi_create_promise(env, &asyncContext->deferred, &result)); | ||
| 96 | + StartUIExtensionAbility(asyncContext); | ||
| 97 | + } | ||
| 98 | + DLP_LOG_DEBUG(LABEL, "end StartDLPManagerForResult"); | ||
| 99 | + return result; | ||
| 100 | +} | ||
| 101 | + | ||
| 102 | +} // namespace DlpPermission | ||
| 103 | +} // namespace Security | ||
| 104 | +} // namespace OHOS | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | - * Copyright (c) 2023-2024 Huawei Device Co., Ltd. | 2 | + * Copyright (c) 2023-2026 Huawei Device Co., Ltd. |
| 3 | * Licensed under the Apache License, Version 2.0 (the "License"); | 3 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | * you may not use this file except in compliance with the License. | 4 | * you may not use this file except in compliance with the License. |
| 5 | * You may obtain a copy of the License at | 5 | * You may obtain a copy of the License at |
| @@ -33,6 +33,7 @@ | |||
| 33 | 33 | ||
| 34 | 34 | ||
| 35 | 35 | ||
| 36 | + | ||
| 36 | 37 | ||
| 37 | namespace OHOS { | 38 | namespace OHOS { |
| 38 | namespace Security { | 39 | namespace Security { |
| @@ -262,6 +263,8 @@ struct UIExtensionRequestContext : public CommonAsyncContext { | |||
| 262 | explicit UIExtensionRequestContext(napi_env env) : CommonAsyncContext(env) {}; | 263 | explicit UIExtensionRequestContext(napi_env env) : CommonAsyncContext(env) {}; |
| 263 | std::shared_ptr<OHOS::AbilityRuntime::AbilityContext> context = nullptr; | 264 | std::shared_ptr<OHOS::AbilityRuntime::AbilityContext> context = nullptr; |
| 264 | OHOS::AAFwk::Want requestWant; | 265 | OHOS::AAFwk::Want requestWant; |
| 266 | + sptr<Rosen::Window> window = nullptr; | ||
| 267 | + OHOS::Ace::UIContent* uiContent = nullptr; | ||
| 265 | }; | 268 | }; |
| 266 | 269 | ||
| 267 | struct SetEnterprisePolicyContext : public CommonAsyncContext { | 270 | struct SetEnterprisePolicyContext : public CommonAsyncContext { |
| @@ -423,8 +426,12 @@ napi_value SandboxInfoToJs(napi_env env, const SandboxInfo& sandboxInfo); | |||
| 423 | 426 | ||
| 424 | bool ParseUIAbilityContextReq( | 427 | bool ParseUIAbilityContextReq( |
| 425 | napi_env env, const napi_value& obj, std::shared_ptr<OHOS::AbilityRuntime::AbilityContext>& abilityContext); | 428 | napi_env env, const napi_value& obj, std::shared_ptr<OHOS::AbilityRuntime::AbilityContext>& abilityContext); |
| 429 | +bool ParseContextReq(napi_env env, const napi_value& obj, | ||
| 430 | + std::shared_ptr<OHOS::AbilityRuntime::AbilityContext>& abilityContext); | ||
| 426 | bool ParseWantReq(napi_env env, const napi_value& obj, OHOS::AAFwk::Want& requestWant); | 431 | bool ParseWantReq(napi_env env, const napi_value& obj, OHOS::AAFwk::Want& requestWant); |
| 427 | void StartUIExtensionAbility(std::shared_ptr<UIExtensionRequestContext> asyncContext); | 432 | void StartUIExtensionAbility(std::shared_ptr<UIExtensionRequestContext> asyncContext); |
| 433 | +bool GetCustomShowingWindow(napi_env env, napi_value windowObj, sptr<Rosen::Window>& window); | ||
| 434 | +void StartUIExtensionAbilityWithWindow(std::shared_ptr<UIExtensionRequestContext> asyncContext); | ||
| 428 | 435 | ||
| 429 | bool IsStringLengthValid(std::string& str, size_t maxLen, size_t minLen = 0); | 436 | bool IsStringLengthValid(std::string& str, size_t maxLen, size_t minLen = 0); |
| 430 | } // namespace DlpPermission | 437 | } // namespace DlpPermission |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | - * Copyright (c) 2023 Huawei Device Co., Ltd. | 2 | + * Copyright (c) 2023-2026 Huawei Device Co., Ltd. |
| 3 | * Licensed under the Apache License, Version 2.0 (the "License"); | 3 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | * you may not use this file except in compliance with the License. | 4 | * you may not use this file except in compliance with the License. |
| 5 | * You may obtain a copy of the License at | 5 | * You may obtain a copy of the License at |
| @@ -1871,155 +1871,40 @@ bool ParseUIAbilityContextReq( | |||
| 1871 | return true; | 1871 | return true; |
| 1872 | } | 1872 | } |
| 1873 | 1873 | ||
| 1874 | -static bool ParseWantUri(napi_env env, const napi_value& obj, OHOS::AAFwk::Want& requestWant, std::string& uri) | 1874 | +bool ParseContextReq(napi_env env, const napi_value& obj, |
| 1875 | + std::shared_ptr<OHOS::AbilityRuntime::AbilityContext>& abilityContext) | ||
| 1875 | { | 1876 | { |
| 1876 | - if (!GetStringValueByKey(env, obj, "uri", uri)) { | 1877 | + DLP_LOG_DEBUG(LABEL, "begin ParseContextReq"); |
| 1877 | - DLP_LOG_ERROR(LABEL, "get uri failed"); | 1878 | + if (obj == nullptr) { |
| 1878 | - DlpNapiThrow(env, ERR_JS_URI_NOT_EXIST, "uri not exist in want"); | 1879 | + DLP_LOG_ERROR(LABEL, "context argument is null"); |
| 1879 | return false; | 1880 | return false; |
| 1880 | } | 1881 | } |
| 1881 | - if (!IsStringLengthValid(uri, MAX_URI_LEN) || uri.empty()) { | 1882 | + napi_valuetype valueType = napi_undefined; |
| 1882 | - DLP_LOG_ERROR(LABEL, "uri length is invalid"); | 1883 | + napi_status typeofStatus = napi_typeof(env, obj, &valueType); |
| 1883 | - DlpNapiThrow(env, ERR_JS_URI_NOT_EXIST, "uri length is invalid"); | 1884 | + if (typeofStatus != napi_ok || valueType != napi_object) { |
| 1885 | + DLP_LOG_ERROR(LABEL, "context argument is not an object"); | ||
| 1884 | return false; | 1886 | return false; |
| 1885 | } | 1887 | } |
| 1886 | - requestWant.SetUri(uri); | 1888 | + // Pre-check stage mode before calling ParseUIAbilityContextReq: for non-AbilityContext |
| 1889 | + // objects (e.g. ServiceExtensionContext) the conversion attempt is expected to fail, | ||
| 1890 | + // and ParseUIAbilityContextReq would log an ERROR, which is misleading for a normal | ||
| 1891 | + // 3-param flow. Only attempt the conversion for genuine stage contexts. | ||
| 1892 | + bool stageMode = false; | ||
| 1893 | + napi_status status = OHOS::AbilityRuntime::IsStageContext(env, obj, stageMode); | ||
| 1894 | + if (status != napi_ok || !stageMode) { | ||
| 1895 | + DLP_LOG_INFO(LABEL, "not a stage context (e.g. ServiceExtensionContext), context field will be null"); | ||
| 1896 | + abilityContext = nullptr; | ||
| 1897 | + return true; | ||
| 1898 | + } | ||
| 1899 | + // This is a stage (AbilityContext-derived) object: parse it for SendMessageBack | ||
| 1900 | + // fallback. Failure here is abnormal and is logged as ERROR inside. | ||
| 1901 | + if (!ParseUIAbilityContextReq(env, obj, abilityContext)) { | ||
| 1902 | + DLP_LOG_INFO(LABEL, "not UIAbilityContext, context field will be null"); | ||
| 1903 | + abilityContext = nullptr; | ||
| 1904 | + } | ||
| 1905 | + DLP_LOG_DEBUG(LABEL, "end ParseContextReq"); | ||
| 1887 | return true; | 1906 | return true; |
| 1888 | } | 1907 | } |
| 1889 | -static bool ParseWantParameters(napi_env env, const napi_value& obj, napi_value& wantParameters) | ||
| 1890 | -{ | ||
| 1891 | - wantParameters = GetNapiValue(env, obj, "parameters"); | ||
| 1892 | - if (wantParameters == nullptr) { | ||
| 1893 | - DLP_LOG_ERROR(LABEL, "get wantParameters failed"); | ||
| 1894 | - DlpNapiThrow(env, ERR_JS_PARAM_DISPLAY_NAME_NOT_EXIST, "parameters not exist in want"); | ||
| 1895 | - return false; | ||
| 1896 | - } | ||
| 1897 | - return true; | ||
| 1898 | -} | ||
| 1899 | -static bool ParseDisplayName(napi_env env, napi_value wantParameters, std::string& displayName) | ||
| 1900 | -{ | ||
| 1901 | - if (!GetStringValueByKey(env, wantParameters, "displayName", displayName)) { | ||
| 1902 | - DLP_LOG_ERROR(LABEL, "get displayName failed"); | ||
| 1903 | - DlpNapiThrow(env, ERR_JS_PARAM_DISPLAY_NAME_NOT_EXIST, "displayName not exist in want parameters"); | ||
| 1904 | - return false; | ||
| 1905 | - } | ||
| 1906 | - if (!IsStringLengthValid(displayName, MAX_FILE_NAME_LEN) || displayName.empty()) { | ||
| 1907 | - DLP_LOG_ERROR(LABEL, "displayName length is invalid"); | ||
| 1908 | - DlpNapiThrow(env, ERR_JS_PARAM_DISPLAY_NAME_NOT_EXIST, "displayName length is invalid"); | ||
| 1909 | - return false; | ||
| 1910 | - } | ||
| 1911 | - return true; | ||
| 1912 | -} | ||
| 1913 | -static void BuildWantParams(AAFwk::WantParams& requestWantParam, const std::string& displayName) | ||
| 1914 | -{ | ||
| 1915 | - requestWantParam.SetParam("displayName", AAFwk::String::Box(displayName)); | ||
| 1916 | - AAFwk::WantParams fileNameObj; | ||
| 1917 | - fileNameObj.SetParam("name", AAFwk::String::Box(displayName)); | ||
| 1918 | - requestWantParam.SetParam("fileName", AAFwk::WantParamWrapper::Box(fileNameObj)); | ||
| 1919 | -} | ||
| 1920 | -static void ParseLinkFileName(napi_env env, napi_value wantParameters, AAFwk::WantParams& requestWantParam) | ||
| 1921 | -{ | ||
| 1922 | - bool ret = false; | ||
| 1923 | - napi_status result = napi_has_named_property(env, wantParameters, "linkFileName", &ret); | ||
| 1924 | - if (result == napi_ok && ret) { | ||
| 1925 | - napi_value linkFileName = GetNapiValue(env, wantParameters, "linkFileName"); | ||
| 1926 | - std::string linkFileNameStr; | ||
| 1927 | - ret = GetStringValueByKey(env, linkFileName, "name", linkFileNameStr) && | ||
| 1928 | - IsStringLengthValid(linkFileNameStr, MAX_FILE_NAME_LEN); | ||
| 1929 | - if (ret && !linkFileNameStr.empty()) { | ||
| 1930 | - AAFwk::WantParams linkFileNameObj; | ||
| 1931 | - linkFileNameObj.SetParam("name", AAFwk::String::Box(linkFileNameStr)); | ||
| 1932 | - requestWantParam.SetParam("linkFileName", AAFwk::WantParamWrapper::Box(linkFileNameObj)); | ||
| 1933 | - DLP_LOG_DEBUG(LABEL, "set linkFileName"); | ||
| 1934 | - } | ||
| 1935 | - } | ||
| 1936 | -} | ||
| 1937 | -bool ParseWantReq(napi_env env, const napi_value& obj, OHOS::AAFwk::Want& requestWant) | ||
| 1938 | -{ | ||
| 1939 | - requestWant.SetElementName(DLP_MANAGER_BUNDLENAME, DLP_MANAGER_ABILITYNAME); | ||
| 1940 | - std::string uri; | ||
| 1941 | - if (!ParseWantUri(env, obj, requestWant, uri)) { | ||
| 1942 | - return false; | ||
| 1943 | - } | ||
| 1944 | - napi_value wantParameters; | ||
| 1945 | - if (!ParseWantParameters(env, obj, wantParameters)) { | ||
| 1946 | - return false; | ||
| 1947 | - } | ||
| 1948 | - std::string displayName; | ||
| 1949 | - if (!ParseDisplayName(env, wantParameters, displayName)) { | ||
| 1950 | - return false; | ||
| 1951 | - } | ||
| 1952 | - AAFwk::WantParams requestWantParam; | ||
| 1953 | - BuildWantParams(requestWantParam, displayName); | ||
| 1954 | - ParseLinkFileName(env, wantParameters, requestWantParam); | ||
| 1955 | - requestWant.SetParams(requestWantParam); | ||
| 1956 | - requestWant.SetParam(PARAM_UI_EXTENSION_TYPE, SYS_COMMON_UI); | ||
| 1957 | - DLP_LOG_DEBUG(LABEL, "end ParseWantReq"); | ||
| 1958 | - return true; | ||
| 1959 | -} | ||
| 1960 | - | ||
| 1961 | -OHOS::Ace::ModalUIExtensionCallbacks CreateExtensionCallbacks( | ||
| 1962 | - std::shared_ptr<UIExtensionCallback>& uiExtCallback) | ||
| 1963 | -{ | ||
| 1964 | - OHOS::Ace::ModalUIExtensionCallbacks extensionCallbacks = { | ||
| 1965 | - [uiExtCallback](int32_t releaseCode) { uiExtCallback->OnRelease(releaseCode); }, | ||
| 1966 | - [uiExtCallback](int32_t resultCode, const OHOS::AAFwk::Want& result) { | ||
| 1967 | - uiExtCallback->OnResult(resultCode, result); }, | ||
| 1968 | - [uiExtCallback](const OHOS::AAFwk::WantParams& request) { uiExtCallback->OnReceive(request); }, | ||
| 1969 | - [uiExtCallback](int32_t errorCode, const std::string& name, const std::string& message) { | ||
| 1970 | - uiExtCallback->OnError(errorCode, name, message); }, | ||
| 1971 | - [uiExtCallback](const std::shared_ptr<OHOS::Ace::ModalUIExtensionProxy>& uiProxy) { | ||
| 1972 | - uiExtCallback->OnRemoteReady(uiProxy); }, | ||
| 1973 | - [uiExtCallback]() { uiExtCallback->OnDestroy(); } | ||
| 1974 | - }; | ||
| 1975 | - return extensionCallbacks; | ||
| 1976 | -} | ||
| 1977 | - | ||
| 1978 | -void StartUIExtensionAbility(std::shared_ptr<UIExtensionRequestContext> asyncContext) | ||
| 1979 | -{ | ||
| 1980 | - DLP_LOG_DEBUG(LABEL, "begin StartUIExtensionAbility"); | ||
| 1981 | - if (asyncContext == nullptr) { | ||
| 1982 | - DLP_LOG_ERROR(LABEL, "asyncContext is null"); | ||
| 1983 | - return; | ||
| 1984 | - } | ||
| 1985 | - int32_t errCode = ERR_JS_INVALID_PARAMETER; | ||
| 1986 | - const char* errMsg = "StartUIExtensionAbility failed"; | ||
| 1987 | - do { | ||
| 1988 | - auto abilityContext = asyncContext->context; | ||
| 1989 | - if (abilityContext == nullptr) { | ||
| 1990 | - DLP_LOG_ERROR(LABEL, "abilityContext is null"); | ||
| 1991 | - errMsg = "abilityContext is null"; | ||
| 1992 | - break; | ||
| 1993 | - } | ||
| 1994 | - auto uiContent = abilityContext->GetUIContent(); | ||
| 1995 | - if (uiContent == nullptr) { | ||
| 1996 | - DLP_LOG_ERROR(LABEL, "uiContent is null"); | ||
| 1997 | - errMsg = "uiContent is null"; | ||
| 1998 | - break; | ||
| 1999 | - } | ||
| 2000 | - | ||
| 2001 | - auto uiExtCallback = std::make_shared<UIExtensionCallback>(asyncContext); | ||
| 2002 | - auto extensionCallbacks = CreateExtensionCallbacks(uiExtCallback); | ||
| 2003 | - | ||
| 2004 | - OHOS::Ace::ModalUIExtensionConfig uiExtConfig; | ||
| 2005 | - uiExtConfig.isProhibitBack = false; | ||
| 2006 | - int32_t sessionId = | ||
| 2007 | - uiContent->CreateModalUIExtension(asyncContext->requestWant, extensionCallbacks, uiExtConfig); | ||
| 2008 | - DLP_LOG_INFO(LABEL, "end CreateModalUIExtension sessionId = %{public}d", sessionId); | ||
| 2009 | - if (sessionId == 0) { | ||
| 2010 | - DLP_LOG_ERROR(LABEL, "CreateModalUIExtension failed, sessionId is %{public}d", sessionId); | ||
| 2011 | - errCode = ERR_JS_SYSTEM_SERVICE_EXCEPTION; | ||
| 2012 | - errMsg = "CreateModalUIExtension failed"; | ||
| 2013 | - break; | ||
| 2014 | - } | ||
| 2015 | - uiExtCallback->SetSessionId(sessionId); | ||
| 2016 | - return; | ||
| 2017 | - } while (0); | ||
| 2018 | - | ||
| 2019 | - napi_value error = GenerateBusinessError(asyncContext->env, errCode, errMsg); | ||
| 2020 | - napi_reject_deferred(asyncContext->env, asyncContext->deferred, error); | ||
| 2021 | - asyncContext->deferred = nullptr; | ||
| 2022 | -} | ||
| 2023 | 1908 | ||
| 2024 | bool IsStringLengthValid(std::string& str, size_t maxLen, size_t minLen) | 1909 | bool IsStringLengthValid(std::string& str, size_t maxLen, size_t minLen) |
| 2025 | { | 1910 | { |
| @@ -2031,110 +1916,6 @@ bool IsStringLengthValid(std::string& str, size_t maxLen, size_t minLen) | |||
| 2031 | return true; | 1916 | return true; |
| 2032 | } | 1917 | } |
| 2033 | 1918 | ||
| 2034 | -UIExtensionCallback::UIExtensionCallback(std::shared_ptr<UIExtensionRequestContext>& reqContext) | ||
| 2035 | -{ | ||
| 2036 | - this->reqContext_ = reqContext; | ||
| 2037 | -} | ||
| 2038 | - | ||
| 2039 | -void UIExtensionCallback::SetSessionId(int32_t sessionId) | ||
| 2040 | -{ | ||
| 2041 | - this->sessionId_ = sessionId; | ||
| 2042 | -} | ||
| 2043 | - | ||
| 2044 | -bool UIExtensionCallback::SetErrorCode(int32_t code) | ||
| 2045 | -{ | ||
| 2046 | - if (this->reqContext_ == nullptr) { | ||
| 2047 | - DLP_LOG_ERROR(LABEL, "OnError reqContext is nullptr"); | ||
| 2048 | - return false; | ||
| 2049 | - } | ||
| 2050 | - if (this->alreadyCallback_) { | ||
| 2051 | - DLP_LOG_DEBUG(LABEL, "alreadyCallback"); | ||
| 2052 | - return false; | ||
| 2053 | - } | ||
| 2054 | - this->alreadyCallback_ = true; | ||
| 2055 | - this->reqContext_->errCode = code; | ||
| 2056 | - return true; | ||
| 2057 | -} | ||
| 2058 | - | ||
| 2059 | -void UIExtensionCallback::OnRelease(int32_t releaseCode) | ||
| 2060 | -{ | ||
| 2061 | - DLP_LOG_DEBUG(LABEL, "UIExtensionComponent OnRelease(), releaseCode = %{public}d", releaseCode); | ||
| 2062 | - if (SetErrorCode(releaseCode)) { | ||
| 2063 | - SendMessageBack(); | ||
| 2064 | - } | ||
| 2065 | -} | ||
| 2066 | - | ||
| 2067 | -void UIExtensionCallback::OnResult(int32_t resultCode, const OHOS::AAFwk::Want& result) | ||
| 2068 | -{ | ||
| 2069 | - DLP_LOG_DEBUG(LABEL, "UIExtensionComponent OnResult(), resultCode = %{public}d", resultCode); | ||
| 2070 | - this->resultCode_ = resultCode; | ||
| 2071 | - this->resultWant_ = result; | ||
| 2072 | - if (SetErrorCode(0)) { | ||
| 2073 | - SendMessageBack(); | ||
| 2074 | - } | ||
| 2075 | -} | ||
| 2076 | - | ||
| 2077 | -void UIExtensionCallback::OnReceive(const OHOS::AAFwk::WantParams& request) | ||
| 2078 | -{ | ||
| 2079 | - DLP_LOG_DEBUG(LABEL, "UIExtensionComponent OnReceive()"); | ||
| 2080 | -} | ||
| 2081 | - | ||
| 2082 | -void UIExtensionCallback::OnError(int32_t errorCode, const std::string& name, const std::string& message) | ||
| 2083 | -{ | ||
| 2084 | - DLP_LOG_ERROR(LABEL, | ||
| 2085 | - "UIExtensionComponent OnError(), errorCode = %{public}d, name = %{public}s, message = %{public}s", | ||
| 2086 | - errorCode, name.c_str(), message.c_str()); | ||
| 2087 | - if (SetErrorCode(errorCode)) { | ||
| 2088 | - SendMessageBack(); | ||
| 2089 | - } | ||
| 2090 | -} | ||
| 2091 | - | ||
| 2092 | -void UIExtensionCallback::OnRemoteReady(const std::shared_ptr<OHOS::Ace::ModalUIExtensionProxy>& uiProxy) | ||
| 2093 | -{ | ||
| 2094 | - DLP_LOG_DEBUG(LABEL, "UIExtensionComponent OnRemoteReady()"); | ||
| 2095 | -} | ||
| 2096 | - | ||
| 2097 | -void UIExtensionCallback::OnDestroy() | ||
| 2098 | -{ | ||
| 2099 | - DLP_LOG_DEBUG(LABEL, "UIExtensionComponent OnDestroy()"); | ||
| 2100 | - if (SetErrorCode(0)) { | ||
| 2101 | - SendMessageBack(); | ||
| 2102 | - } | ||
| 2103 | -} | ||
| 2104 | - | ||
| 2105 | -void UIExtensionCallback::SendMessageBack() | ||
| 2106 | -{ | ||
| 2107 | - DLP_LOG_INFO(LABEL, "start SendMessageBack"); | ||
| 2108 | - if (this->reqContext_ == nullptr) { | ||
| 2109 | - DLP_LOG_ERROR(LABEL, "reqContext is nullptr"); | ||
| 2110 | - return; | ||
| 2111 | - } | ||
| 2112 | - | ||
| 2113 | - auto abilityContext = this->reqContext_->context; | ||
| 2114 | - if (abilityContext != nullptr) { | ||
| 2115 | - auto uiContent = abilityContext->GetUIContent(); | ||
| 2116 | - if (uiContent != nullptr) { | ||
| 2117 | - DLP_LOG_DEBUG(LABEL, "CloseModalUIExtension"); | ||
| 2118 | - uiContent->CloseModalUIExtension(this->sessionId_); | ||
| 2119 | - } | ||
| 2120 | - } | ||
| 2121 | - | ||
| 2122 | - napi_value nativeObjJs = nullptr; | ||
| 2123 | - NAPI_CALL_RETURN_VOID(this->reqContext_->env, napi_create_object(this->reqContext_->env, &nativeObjJs)); | ||
| 2124 | - napi_value resultCode = nullptr; | ||
| 2125 | - NAPI_CALL_RETURN_VOID(this->reqContext_->env, | ||
| 2126 | - napi_create_int32(this->reqContext_->env, this->resultCode_, &resultCode)); | ||
| 2127 | - NAPI_CALL_RETURN_VOID(this->reqContext_->env, | ||
| 2128 | - napi_set_named_property(this->reqContext_->env, nativeObjJs, "resultCode", resultCode)); | ||
| 2129 | - napi_value resultWant = nullptr; | ||
| 2130 | - resultWant = OHOS::AppExecFwk::WrapWant(this->reqContext_->env, this->resultWant_); | ||
| 2131 | - NAPI_CALL_RETURN_VOID(this->reqContext_->env, | ||
| 2132 | - napi_set_named_property(this->reqContext_->env, nativeObjJs, "want", resultWant)); | ||
| 2133 | - | ||
| 2134 | - DLP_LOG_DEBUG(LABEL, "ProcessCallbackOrPromise"); | ||
| 2135 | - ProcessCallbackOrPromise(this->reqContext_->env, this->reqContext_.get(), nativeObjJs); | ||
| 2136 | -} | ||
| 2137 | - | ||
| 2138 | } // namespace DlpPermission | 1919 | } // namespace DlpPermission |
| 2139 | } // namespace Security | 1920 | } // namespace Security |
| 2140 | } // namespace OHOS | 1921 | } // namespace OHOS |
| @@ -0,0 +1,458 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (c) 2026 Huawei Device Co., Ltd. | ||
| 3 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | + * you may not use this file except in compliance with the License. | ||
| 5 | + * You may obtain a copy of the License at | ||
| 6 | + * | ||
| 7 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | + * | ||
| 9 | + * Unless required by applicable law or agreed to in writing, software | ||
| 10 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | + * See the License for the specific language governing permissions and | ||
| 13 | + * limitations under the License. | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | +namespace OHOS { | ||
| 23 | +namespace Security { | ||
| 24 | +namespace DlpPermission { | ||
| 25 | +namespace { | ||
| 26 | +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { | ||
| 27 | + LOG_CORE, SECURITY_DOMAIN_DLP_PERMISSION, "DlpPermissionCommon"}; | ||
| 28 | +const std::string PARAM_UI_EXTENSION_TYPE = "ability.want.params.uiExtensionType"; | ||
| 29 | +const std::string SYS_COMMON_UI = "sys/commonUI"; | ||
| 30 | +const std::string DLP_MANAGER_BUNDLENAME = "com.ohos.dlpmanager"; | ||
| 31 | +const std::string DLP_MANAGER_ABILITYNAME = "MainAbilityEx"; | ||
| 32 | +static constexpr size_t MAX_FILE_NAME_LEN = 255; | ||
| 33 | +static constexpr size_t MAX_URI_LEN = 4095; | ||
| 34 | + | ||
| 35 | +static bool ParseWantUri(napi_env env, const napi_value& obj, OHOS::AAFwk::Want& requestWant, std::string& uri) | ||
| 36 | +{ | ||
| 37 | + if (!GetStringValueByKey(env, obj, "uri", uri)) { | ||
| 38 | + DLP_LOG_ERROR(LABEL, "get uri failed"); | ||
| 39 | + DlpNapiThrow(env, ERR_JS_URI_NOT_EXIST, "uri not exist in want"); | ||
| 40 | + return false; | ||
| 41 | + } | ||
| 42 | + if (!IsStringLengthValid(uri, MAX_URI_LEN) || uri.empty()) { | ||
| 43 | + DLP_LOG_ERROR(LABEL, "uri length is invalid"); | ||
| 44 | + DlpNapiThrow(env, ERR_JS_URI_NOT_EXIST, "uri length is invalid"); | ||
| 45 | + return false; | ||
| 46 | + } | ||
| 47 | + requestWant.SetUri(uri); | ||
| 48 | + return true; | ||
| 49 | +} | ||
| 50 | + | ||
| 51 | +static bool ParseWantParameters(napi_env env, const napi_value& obj, napi_value& wantParameters) | ||
| 52 | +{ | ||
| 53 | + wantParameters = GetNapiValue(env, obj, "parameters"); | ||
| 54 | + if (wantParameters == nullptr) { | ||
| 55 | + DLP_LOG_ERROR(LABEL, "get wantParameters failed"); | ||
| 56 | + DlpNapiThrow(env, ERR_JS_PARAM_DISPLAY_NAME_NOT_EXIST, "parameters not exist in want"); | ||
| 57 | + return false; | ||
| 58 | + } | ||
| 59 | + return true; | ||
| 60 | +} | ||
| 61 | + | ||
| 62 | +static bool ParseDisplayName(napi_env env, napi_value wantParameters, std::string& displayName) | ||
| 63 | +{ | ||
| 64 | + if (!GetStringValueByKey(env, wantParameters, "displayName", displayName)) { | ||
| 65 | + DLP_LOG_ERROR(LABEL, "get displayName failed"); | ||
| 66 | + DlpNapiThrow(env, ERR_JS_PARAM_DISPLAY_NAME_NOT_EXIST, "displayName not exist in want parameters"); | ||
| 67 | + return false; | ||
| 68 | + } | ||
| 69 | + if (!IsStringLengthValid(displayName, MAX_FILE_NAME_LEN) || displayName.empty()) { | ||
| 70 | + DLP_LOG_ERROR(LABEL, "displayName length is invalid"); | ||
| 71 | + DlpNapiThrow(env, ERR_JS_PARAM_DISPLAY_NAME_NOT_EXIST, "displayName length is invalid"); | ||
| 72 | + return false; | ||
| 73 | + } | ||
| 74 | + return true; | ||
| 75 | +} | ||
| 76 | + | ||
| 77 | +static void BuildWantParams(AAFwk::WantParams& requestWantParam, const std::string& displayName) | ||
| 78 | +{ | ||
| 79 | + requestWantParam.SetParam("displayName", AAFwk::String::Box(displayName)); | ||
| 80 | + AAFwk::WantParams fileNameObj; | ||
| 81 | + fileNameObj.SetParam("name", AAFwk::String::Box(displayName)); | ||
| 82 | + requestWantParam.SetParam("fileName", AAFwk::WantParamWrapper::Box(fileNameObj)); | ||
| 83 | +} | ||
| 84 | + | ||
| 85 | +static void ParseLinkFileName(napi_env env, napi_value wantParameters, AAFwk::WantParams& requestWantParam) | ||
| 86 | +{ | ||
| 87 | + bool ret = false; | ||
| 88 | + napi_status result = napi_has_named_property(env, wantParameters, "linkFileName", &ret); | ||
| 89 | + if (result == napi_ok && ret) { | ||
| 90 | + napi_value linkFileName = GetNapiValue(env, wantParameters, "linkFileName"); | ||
| 91 | + std::string linkFileNameStr; | ||
| 92 | + if (!GetStringValueByKey(env, linkFileName, "name", linkFileNameStr)) { | ||
| 93 | + DLP_LOG_ERROR(LABEL, "linkFileName.name is not a valid string"); | ||
| 94 | + return; | ||
| 95 | + } | ||
| 96 | + if (!IsStringLengthValid(linkFileNameStr, MAX_FILE_NAME_LEN)) { | ||
| 97 | + DLP_LOG_ERROR(LABEL, "linkFileName.name length exceeds limit, len=%{public}zu", | ||
| 98 | + linkFileNameStr.length()); | ||
| 99 | + return; | ||
| 100 | + } | ||
| 101 | + if (!linkFileNameStr.empty()) { | ||
| 102 | + AAFwk::WantParams linkFileNameObj; | ||
| 103 | + linkFileNameObj.SetParam("name", AAFwk::String::Box(linkFileNameStr)); | ||
| 104 | + requestWantParam.SetParam("linkFileName", AAFwk::WantParamWrapper::Box(linkFileNameObj)); | ||
| 105 | + DLP_LOG_DEBUG(LABEL, "set linkFileName"); | ||
| 106 | + } | ||
| 107 | + } | ||
| 108 | +} | ||
| 109 | + | ||
| 110 | +static bool GetWindowProperties(napi_env env, napi_value windowObj, napi_value& properties) | ||
| 111 | +{ | ||
| 112 | + napi_value getPropertiesFunc = nullptr; | ||
| 113 | + napi_status getStatus = napi_get_named_property(env, windowObj, "getWindowProperties", &getPropertiesFunc); | ||
| 114 | + if (getStatus != napi_ok) { | ||
| 115 | + DLP_LOG_ERROR(LABEL, "napi_get_named_property getWindowProperties failed"); | ||
| 116 | + return false; | ||
| 117 | + } | ||
| 118 | + napi_valuetype funcType = napi_undefined; | ||
| 119 | + napi_status typeofStatus = napi_typeof(env, getPropertiesFunc, &funcType); | ||
| 120 | + if (typeofStatus != napi_ok || funcType != napi_function) { | ||
| 121 | + DLP_LOG_ERROR(LABEL, "getWindowProperties is not a function"); | ||
| 122 | + return false; | ||
| 123 | + } | ||
| 124 | + napi_status callStatus = napi_call_function(env, windowObj, getPropertiesFunc, 0, nullptr, &properties); | ||
| 125 | + if (callStatus != napi_ok || properties == nullptr) { | ||
| 126 | + DLP_LOG_ERROR(LABEL, "getPropertiesFunc call failed or returned null"); | ||
| 127 | + return false; | ||
| 128 | + } | ||
| 129 | + return true; | ||
| 130 | +} | ||
| 131 | + | ||
| 132 | +static bool GetWindowNameFromProperties(napi_env env, napi_value properties, std::string& windowName) | ||
| 133 | +{ | ||
| 134 | + napi_value nameValue = nullptr; | ||
| 135 | + napi_status getStatus = napi_get_named_property(env, properties, "name", &nameValue); | ||
| 136 | + if (getStatus != napi_ok || nameValue == nullptr) { | ||
| 137 | + DLP_LOG_ERROR(LABEL, "Failed to get window name"); | ||
| 138 | + return false; | ||
| 139 | + } | ||
| 140 | + napi_valuetype nameType = napi_undefined; | ||
| 141 | + napi_status typeofStatus = napi_typeof(env, nameValue, &nameType); | ||
| 142 | + if (typeofStatus != napi_ok || nameType != napi_string) { | ||
| 143 | + DLP_LOG_ERROR(LABEL, "Window name is not a string"); | ||
| 144 | + return false; | ||
| 145 | + } | ||
| 146 | + size_t nameLen = 0; | ||
| 147 | + napi_status strStatus = napi_get_value_string_utf8(env, nameValue, nullptr, 0, &nameLen); | ||
| 148 | + if (strStatus != napi_ok) { | ||
| 149 | + DLP_LOG_ERROR(LABEL, "napi_get_value_string_utf8 get length failed for window name"); | ||
| 150 | + return false; | ||
| 151 | + } | ||
| 152 | + if (nameLen == 0 || nameLen > MAX_FILE_NAME_LEN) { | ||
| 153 | + DLP_LOG_ERROR(LABEL, "Window name length is invalid, len=%{public}zu", nameLen); | ||
| 154 | + return false; | ||
| 155 | + } | ||
| 156 | + windowName.reserve(nameLen + 1); | ||
| 157 | + windowName.resize(nameLen); | ||
| 158 | + strStatus = napi_get_value_string_utf8(env, nameValue, windowName.data(), nameLen + 1, &nameLen); | ||
| 159 | + if (strStatus != napi_ok) { | ||
| 160 | + DLP_LOG_ERROR(LABEL, "napi_get_value_string_utf8 failed for window name"); | ||
| 161 | + return false; | ||
| 162 | + } | ||
| 163 | + DLP_LOG_INFO(LABEL, "Got window name: %{public}s", windowName.c_str()); | ||
| 164 | + return true; | ||
| 165 | +} | ||
| 166 | + | ||
| 167 | +static bool GetWindowNameFromObj(napi_env env, napi_value windowObj, std::string& windowName) | ||
| 168 | +{ | ||
| 169 | + DLP_LOG_DEBUG(LABEL, "begin GetWindowNameFromObj"); | ||
| 170 | + napi_value properties = nullptr; | ||
| 171 | + if (!GetWindowProperties(env, windowObj, properties)) { | ||
| 172 | + DLP_LOG_ERROR(LABEL, "GetWindowProperties failed"); | ||
| 173 | + return false; | ||
| 174 | + } | ||
| 175 | + return GetWindowNameFromProperties(env, properties, windowName); | ||
| 176 | +} | ||
| 177 | +} // namespace | ||
| 178 | + | ||
| 179 | +bool ParseWantReq(napi_env env, const napi_value& obj, OHOS::AAFwk::Want& requestWant) | ||
| 180 | +{ | ||
| 181 | + requestWant.SetElementName(DLP_MANAGER_BUNDLENAME, DLP_MANAGER_ABILITYNAME); | ||
| 182 | + std::string uri; | ||
| 183 | + if (!ParseWantUri(env, obj, requestWant, uri)) { | ||
| 184 | + return false; | ||
| 185 | + } | ||
| 186 | + napi_value wantParameters; | ||
| 187 | + if (!ParseWantParameters(env, obj, wantParameters)) { | ||
| 188 | + return false; | ||
| 189 | + } | ||
| 190 | + std::string displayName; | ||
| 191 | + if (!ParseDisplayName(env, wantParameters, displayName)) { | ||
| 192 | + return false; | ||
| 193 | + } | ||
| 194 | + AAFwk::WantParams requestWantParam; | ||
| 195 | + BuildWantParams(requestWantParam, displayName); | ||
| 196 | + ParseLinkFileName(env, wantParameters, requestWantParam); | ||
| 197 | + requestWant.SetParams(requestWantParam); | ||
| 198 | + requestWant.SetParam(PARAM_UI_EXTENSION_TYPE, SYS_COMMON_UI); | ||
| 199 | + DLP_LOG_DEBUG(LABEL, "end ParseWantReq"); | ||
| 200 | + return true; | ||
| 201 | +} | ||
| 202 | + | ||
| 203 | +OHOS::Ace::ModalUIExtensionCallbacks CreateExtensionCallbacks( | ||
| 204 | + std::shared_ptr<UIExtensionCallback>& uiExtCallback) | ||
| 205 | +{ | ||
| 206 | + OHOS::Ace::ModalUIExtensionCallbacks extensionCallbacks = { | ||
| 207 | + [uiExtCallback](int32_t releaseCode) { uiExtCallback->OnRelease(releaseCode); }, | ||
| 208 | + [uiExtCallback](int32_t resultCode, const OHOS::AAFwk::Want& result) { | ||
| 209 | + uiExtCallback->OnResult(resultCode, result); }, | ||
| 210 | + [uiExtCallback](const OHOS::AAFwk::WantParams& request) { uiExtCallback->OnReceive(request); }, | ||
| 211 | + [uiExtCallback](int32_t errorCode, const std::string& name, const std::string& message) { | ||
| 212 | + uiExtCallback->OnError(errorCode, name, message); }, | ||
| 213 | + [uiExtCallback](const std::shared_ptr<OHOS::Ace::ModalUIExtensionProxy>& uiProxy) { | ||
| 214 | + uiExtCallback->OnRemoteReady(uiProxy); }, | ||
| 215 | + [uiExtCallback]() { uiExtCallback->OnDestroy(); } | ||
| 216 | + }; | ||
| 217 | + return extensionCallbacks; | ||
| 218 | +} | ||
| 219 | + | ||
| 220 | +void StartUIExtensionAbility(std::shared_ptr<UIExtensionRequestContext> asyncContext) | ||
| 221 | +{ | ||
| 222 | + DLP_LOG_DEBUG(LABEL, "begin StartUIExtensionAbility"); | ||
| 223 | + if (asyncContext == nullptr) { | ||
| 224 | + DLP_LOG_ERROR(LABEL, "asyncContext is null"); | ||
| 225 | + return; | ||
| 226 | + } | ||
| 227 | + int32_t errCode = ERR_JS_INVALID_PARAMETER; | ||
| 228 | + const char* errMsg = "StartUIExtensionAbility failed"; | ||
| 229 | + do { | ||
| 230 | + auto abilityContext = asyncContext->context; | ||
| 231 | + if (abilityContext == nullptr) { | ||
| 232 | + DLP_LOG_ERROR(LABEL, "abilityContext is null"); | ||
| 233 | + errMsg = "abilityContext is null"; | ||
| 234 | + break; | ||
| 235 | + } | ||
| 236 | + auto uiContent = abilityContext->GetUIContent(); | ||
| 237 | + if (uiContent == nullptr) { | ||
| 238 | + DLP_LOG_ERROR(LABEL, "uiContent is null"); | ||
| 239 | + errMsg = "uiContent is null"; | ||
| 240 | + break; | ||
| 241 | + } | ||
| 242 | + | ||
| 243 | + auto uiExtCallback = std::make_shared<UIExtensionCallback>(asyncContext); | ||
| 244 | + auto extensionCallbacks = CreateExtensionCallbacks(uiExtCallback); | ||
| 245 | + | ||
| 246 | + OHOS::Ace::ModalUIExtensionConfig uiExtConfig; | ||
| 247 | + uiExtConfig.isProhibitBack = false; | ||
| 248 | + int32_t sessionId = | ||
| 249 | + uiContent->CreateModalUIExtension(asyncContext->requestWant, extensionCallbacks, uiExtConfig); | ||
| 250 | + DLP_LOG_INFO(LABEL, "end CreateModalUIExtension sessionId = %{public}d", sessionId); | ||
| 251 | + if (sessionId == 0) { | ||
| 252 | + DLP_LOG_ERROR(LABEL, "CreateModalUIExtension failed, sessionId is %{public}d", sessionId); | ||
| 253 | + errCode = ERR_JS_SYSTEM_SERVICE_EXCEPTION; | ||
| 254 | + errMsg = "CreateModalUIExtension failed"; | ||
| 255 | + break; | ||
| 256 | + } | ||
| 257 | + uiExtCallback->SetSessionId(sessionId); | ||
| 258 | + return; | ||
| 259 | + } while (0); | ||
| 260 | + | ||
| 261 | + napi_value error = GenerateBusinessError(asyncContext->env, errCode, errMsg); | ||
| 262 | + napi_reject_deferred(asyncContext->env, asyncContext->deferred, error); | ||
| 263 | + asyncContext->deferred = nullptr; | ||
| 264 | +} | ||
| 265 | + | ||
| 266 | +bool GetCustomShowingWindow(napi_env env, napi_value windowObj, sptr<Rosen::Window>& window) | ||
| 267 | +{ | ||
| 268 | + DLP_LOG_DEBUG(LABEL, "begin GetCustomShowingWindow"); | ||
| 269 | + if (windowObj == nullptr) { | ||
| 270 | + DLP_LOG_ERROR(LABEL, "window argument is null"); | ||
| 271 | + return false; | ||
| 272 | + } | ||
| 273 | + napi_valuetype valueType = napi_undefined; | ||
| 274 | + napi_status typeofStatus = napi_typeof(env, windowObj, &valueType); | ||
| 275 | + if (typeofStatus != napi_ok || valueType != napi_object) { | ||
| 276 | + DLP_LOG_ERROR(LABEL, "Window argument is not an object"); | ||
| 277 | + return false; | ||
| 278 | + } | ||
| 279 | + std::string windowName; | ||
| 280 | + if (!GetWindowNameFromObj(env, windowObj, windowName)) { | ||
| 281 | + DLP_LOG_ERROR(LABEL, "GetWindowNameFromObj failed"); | ||
| 282 | + return false; | ||
| 283 | + } | ||
| 284 | + auto foundWindow = Rosen::Window::Find(windowName); | ||
| 285 | + if (foundWindow == nullptr) { | ||
| 286 | + DLP_LOG_ERROR(LABEL, "Window not found by name: %{public}s", windowName.c_str()); | ||
| 287 | + return false; | ||
| 288 | + } | ||
| 289 | + window = foundWindow; | ||
| 290 | + DLP_LOG_INFO(LABEL, "GetCustomShowingWindow success"); | ||
| 291 | + return true; | ||
| 292 | +} | ||
| 293 | + | ||
| 294 | +void StartUIExtensionAbilityWithWindow(std::shared_ptr<UIExtensionRequestContext> asyncContext) | ||
| 295 | +{ | ||
| 296 | + DLP_LOG_DEBUG(LABEL, "begin StartUIExtensionAbilityWithWindow"); | ||
| 297 | + if (asyncContext == nullptr) { | ||
| 298 | + DLP_LOG_ERROR(LABEL, "asyncContext is null"); | ||
| 299 | + return; | ||
| 300 | + } | ||
| 301 | + int32_t errCode = ERR_JS_INVALID_PARAMETER; | ||
| 302 | + const char* errMsg = "StartUIExtensionAbilityWithWindow failed"; | ||
| 303 | + do { | ||
| 304 | + auto window = asyncContext->window; | ||
| 305 | + if (window == nullptr) { | ||
| 306 | + DLP_LOG_ERROR(LABEL, "window is null"); | ||
| 307 | + errMsg = "window is null"; | ||
| 308 | + break; | ||
| 309 | + } | ||
| 310 | + auto uiContent = window->GetUIContent(); | ||
| 311 | + if (uiContent == nullptr) { | ||
| 312 | + DLP_LOG_ERROR(LABEL, "uiContent is null"); | ||
| 313 | + errMsg = "uiContent is null"; | ||
| 314 | + break; | ||
| 315 | + } | ||
| 316 | + asyncContext->uiContent = uiContent; | ||
| 317 | + | ||
| 318 | + auto uiExtCallback = std::make_shared<UIExtensionCallback>(asyncContext); | ||
| 319 | + auto extensionCallbacks = CreateExtensionCallbacks(uiExtCallback); | ||
| 320 | + | ||
| 321 | + OHOS::Ace::ModalUIExtensionConfig uiExtConfig; | ||
| 322 | + uiExtConfig.isProhibitBack = false; | ||
| 323 | + int32_t sessionId = | ||
| 324 | + uiContent->CreateModalUIExtension(asyncContext->requestWant, extensionCallbacks, uiExtConfig); | ||
| 325 | + DLP_LOG_INFO(LABEL, "end CreateModalUIExtension sessionId = %{public}d", sessionId); | ||
| 326 | + if (sessionId == 0) { | ||
| 327 | + DLP_LOG_ERROR(LABEL, "CreateModalUIExtension failed, sessionId is %{public}d", sessionId); | ||
| 328 | + errCode = ERR_JS_SYSTEM_SERVICE_EXCEPTION; | ||
| 329 | + errMsg = "CreateModalUIExtension failed"; | ||
| 330 | + break; | ||
| 331 | + } | ||
| 332 | + uiExtCallback->SetSessionId(sessionId); | ||
| 333 | + return; | ||
| 334 | + } while (0); | ||
| 335 | + | ||
| 336 | + napi_value error = GenerateBusinessError(asyncContext->env, errCode, errMsg); | ||
| 337 | + napi_reject_deferred(asyncContext->env, asyncContext->deferred, error); | ||
| 338 | + asyncContext->deferred = nullptr; | ||
| 339 | +} | ||
| 340 | + | ||
| 341 | +UIExtensionCallback::UIExtensionCallback(std::shared_ptr<UIExtensionRequestContext>& reqContext) | ||
| 342 | +{ | ||
| 343 | + this->reqContext_ = reqContext; | ||
| 344 | +} | ||
| 345 | + | ||
| 346 | +void UIExtensionCallback::SetSessionId(int32_t sessionId) | ||
| 347 | +{ | ||
| 348 | + this->sessionId_ = sessionId; | ||
| 349 | +} | ||
| 350 | + | ||
| 351 | +bool UIExtensionCallback::SetErrorCode(int32_t code) | ||
| 352 | +{ | ||
| 353 | + if (this->reqContext_ == nullptr) { | ||
| 354 | + DLP_LOG_ERROR(LABEL, "OnError reqContext is nullptr"); | ||
| 355 | + return false; | ||
| 356 | + } | ||
| 357 | + if (this->alreadyCallback_) { | ||
| 358 | + DLP_LOG_DEBUG(LABEL, "alreadyCallback"); | ||
| 359 | + return false; | ||
| 360 | + } | ||
| 361 | + this->alreadyCallback_ = true; | ||
| 362 | + this->reqContext_->errCode = code; | ||
| 363 | + return true; | ||
| 364 | +} | ||
| 365 | + | ||
| 366 | +void UIExtensionCallback::OnRelease(int32_t releaseCode) | ||
| 367 | +{ | ||
| 368 | + DLP_LOG_DEBUG(LABEL, "UIExtensionComponent OnRelease(), releaseCode = %{public}d", releaseCode); | ||
| 369 | + if (SetErrorCode(releaseCode)) { | ||
| 370 | + SendMessageBack(); | ||
| 371 | + } | ||
| 372 | +} | ||
| 373 | + | ||
| 374 | +void UIExtensionCallback::OnResult(int32_t resultCode, const OHOS::AAFwk::Want& result) | ||
| 375 | +{ | ||
| 376 | + DLP_LOG_DEBUG(LABEL, "UIExtensionComponent OnResult(), resultCode = %{public}d", resultCode); | ||
| 377 | + this->resultCode_ = resultCode; | ||
| 378 | + this->resultWant_ = result; | ||
| 379 | + if (SetErrorCode(0)) { | ||
| 380 | + SendMessageBack(); | ||
| 381 | + } | ||
| 382 | +} | ||
| 383 | + | ||
| 384 | +void UIExtensionCallback::OnReceive(const OHOS::AAFwk::WantParams& request) | ||
| 385 | +{ | ||
| 386 | + DLP_LOG_DEBUG(LABEL, "UIExtensionComponent OnReceive()"); | ||
| 387 | +} | ||
| 388 | + | ||
| 389 | +void UIExtensionCallback::OnError(int32_t errorCode, const std::string& name, const std::string& message) | ||
| 390 | +{ | ||
| 391 | + DLP_LOG_ERROR(LABEL, | ||
| 392 | + "UIExtensionComponent OnError(), errorCode = %{public}d, name = %{public}s, message = %{public}s", | ||
| 393 | + errorCode, name.c_str(), message.c_str()); | ||
| 394 | + if (SetErrorCode(errorCode)) { | ||
| 395 | + SendMessageBack(); | ||
| 396 | + } | ||
| 397 | +} | ||
| 398 | + | ||
| 399 | +void UIExtensionCallback::OnRemoteReady(const std::shared_ptr<OHOS::Ace::ModalUIExtensionProxy>& uiProxy) | ||
| 400 | +{ | ||
| 401 | + DLP_LOG_DEBUG(LABEL, "UIExtensionComponent OnRemoteReady()"); | ||
| 402 | +} | ||
| 403 | + | ||
| 404 | +void UIExtensionCallback::OnDestroy() | ||
| 405 | +{ | ||
| 406 | + DLP_LOG_DEBUG(LABEL, "UIExtensionComponent OnDestroy()"); | ||
| 407 | + if (SetErrorCode(0)) { | ||
| 408 | + SendMessageBack(); | ||
| 409 | + } | ||
| 410 | +} | ||
| 411 | + | ||
| 412 | +void UIExtensionCallback::SendMessageBack() | ||
| 413 | +{ | ||
| 414 | + DLP_LOG_INFO(LABEL, "start SendMessageBack"); | ||
| 415 | + if (this->reqContext_ == nullptr) { | ||
| 416 | + DLP_LOG_ERROR(LABEL, "reqContext is nullptr"); | ||
| 417 | + return; | ||
| 418 | + } | ||
| 419 | + | ||
| 420 | + if (this->reqContext_->uiContent != nullptr) { | ||
| 421 | + DLP_LOG_DEBUG(LABEL, "CloseModalUIExtension via window uiContent"); | ||
| 422 | + this->reqContext_->uiContent->CloseModalUIExtension(this->sessionId_); | ||
| 423 | + } else { | ||
| 424 | + auto abilityContext = this->reqContext_->context; | ||
| 425 | + if (abilityContext != nullptr) { | ||
| 426 | + auto uiContent = abilityContext->GetUIContent(); | ||
| 427 | + if (uiContent != nullptr) { | ||
| 428 | + DLP_LOG_DEBUG(LABEL, "CloseModalUIExtension"); | ||
| 429 | + uiContent->CloseModalUIExtension(this->sessionId_); | ||
| 430 | + } | ||
| 431 | + } | ||
| 432 | + } | ||
| 433 | + | ||
| 434 | + if (this->reqContext_->window != nullptr) { | ||
| 435 | + DLP_LOG_WARN(LABEL, | ||
| 436 | + "SendMessageBack: caller-provided window is still alive after modal closed. " | ||
| 437 | + "Caller MUST call window.destroyWindow() to release it, otherwise the window will leak."); | ||
| 438 | + } | ||
| 439 | + | ||
| 440 | + napi_value nativeObjJs = nullptr; | ||
| 441 | + NAPI_CALL_RETURN_VOID(this->reqContext_->env, napi_create_object(this->reqContext_->env, &nativeObjJs)); | ||
| 442 | + napi_value resultCode = nullptr; | ||
| 443 | + NAPI_CALL_RETURN_VOID(this->reqContext_->env, | ||
| 444 | + napi_create_int32(this->reqContext_->env, this->resultCode_, &resultCode)); | ||
| 445 | + NAPI_CALL_RETURN_VOID(this->reqContext_->env, | ||
| 446 | + napi_set_named_property(this->reqContext_->env, nativeObjJs, "resultCode", resultCode)); | ||
| 447 | + napi_value resultWant = nullptr; | ||
| 448 | + resultWant = OHOS::AppExecFwk::WrapWant(this->reqContext_->env, this->resultWant_); | ||
| 449 | + NAPI_CALL_RETURN_VOID(this->reqContext_->env, | ||
| 450 | + napi_set_named_property(this->reqContext_->env, nativeObjJs, "want", resultWant)); | ||
| 451 | + | ||
| 452 | + DLP_LOG_DEBUG(LABEL, "ProcessCallbackOrPromise"); | ||
| 453 | + ProcessCallbackOrPromise(this->reqContext_->env, this->reqContext_.get(), nativeObjJs); | ||
| 454 | +} | ||
| 455 | + | ||
| 456 | +} // namespace DlpPermission | ||
| 457 | +} // namespace Security | ||
| 458 | +} // namespace OHOS | ||