已合并
新增支持传入窗口参数拉起加密保护页面功能 #907
新增支持传入窗口参数拉起加密保护页面功能 #907
已合并
0202zc创建于 11 天前
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 at4# 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 at5 * 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 at5 * 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- 
2083void NapiDlpPermission::InitFunction(napi_env env, napi_value exports)2042void 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+#include "napi_dlp_permission.h"
17+#include <string>
18+#include "dlp_permission_log.h"
19+#include "napi_error_msg.h"
20+#include "napi/native_api.h"
21+#include "napi/native_node_api.h"
22+#include "napi_common.h"
23+#include "napi_dlp_permission_common.h"
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 at5 * You may obtain a copy of the License at
@@ -33,6 +33,7 @@
33#include "retention_sandbox_info.h"33#include "retention_sandbox_info.h"
34#include "ui_content.h"34#include "ui_content.h"
35#include "visited_dlp_file_info.h"35#include "visited_dlp_file_info.h"
36+#include "window.h"
36 37 
37namespace OHOS {38namespace OHOS {
38namespace Security {39namespace 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 
267struct SetEnterprisePolicyContext : public CommonAsyncContext {270struct SetEnterprisePolicyContext : public CommonAsyncContext {
@@ -423,8 +426,12 @@ napi_value SandboxInfoToJs(napi_env env, const SandboxInfo& sandboxInfo);
423 426 
424bool ParseUIAbilityContextReq(427bool 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);
426bool ParseWantReq(napi_env env, const napi_value& obj, OHOS::AAFwk::Want& requestWant);431bool ParseWantReq(napi_env env, const napi_value& obj, OHOS::AAFwk::Want& requestWant);
427void StartUIExtensionAbility(std::shared_ptr<UIExtensionRequestContext> asyncContext);432void 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 
429bool IsStringLengthValid(std::string& str, size_t maxLen, size_t minLen = 0);436bool IsStringLengthValid(std::string& str, size_t maxLen, size_t minLen = 0);
430} // namespace DlpPermission437} // 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 at5 * 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 
2024bool IsStringLengthValid(std::string& str, size_t maxLen, size_t minLen)1909bool 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 DlpPermission1919} // namespace DlpPermission
2139} // namespace Security1920} // namespace Security
2140} // namespace OHOS1921} // 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+#include "napi_common.h"
17+#include "dlp_permission_log.h"
18+#include "napi_error_msg.h"
19+#include "string_wrapper.h"
20+#include "want_params_wrapper.h"
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