1 /*
2 * Copyright (c) 2024 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 #include "napi_request_permission_on_setting.h"
16
17 #include "ability.h"
18 #include "accesstoken_kit.h"
19 #include "accesstoken_common_log.h"
20 #include "napi_base_context.h"
21 #include "token_setproc.h"
22 #include "want.h"
23
24 namespace OHOS {
25 namespace Security {
26 namespace AccessToken {
27 namespace {
28 const std::string PERMISSION_KEY = "ohos.user.setting.permission";
29 const std::string PERMISSION_RESULT_KEY = "ohos.user.setting.permission.result";
30 const std::string RESULT_ERROR_KEY = "ohos.user.setting.error_code";
31 const std::string EXTENSION_TYPE_KEY = "ability.want.params.uiExtensionType";
32 const std::string UI_EXTENSION_TYPE = "sys/commonUI";
33
34 // error code from dialog
35 const int32_t REQUEST_REALDY_EXIST = 1;
36 const int32_t PERM_NOT_BELONG_TO_SAME_GROUP = 2;
37 const int32_t PERM_IS_NOT_DECLARE = 3;
38 const int32_t ALL_PERM_GRANTED = 4;
39 const int32_t PERM_REVOKE_BY_USER = 5;
40 std::mutex g_lockFlag;
41 } // namespace
ReturnPromiseResult(napi_env env,int32_t jsCode,napi_deferred deferred,napi_value result)42 static void ReturnPromiseResult(napi_env env, int32_t jsCode, napi_deferred deferred, napi_value result)
43 {
44 if (jsCode != JS_OK) {
45 napi_value businessError = GenerateBusinessError(env, jsCode, GetErrorMessage(jsCode));
46 NAPI_CALL_RETURN_VOID(env, napi_reject_deferred(env, deferred, businessError));
47 } else {
48 NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, deferred, result));
49 }
50 }
51
WrapVoidToJS(napi_env env)52 static napi_value WrapVoidToJS(napi_env env)
53 {
54 napi_value result = nullptr;
55 NAPI_CALL(env, napi_get_null(env, &result));
56 return result;
57 }
58
GetUIContent(std::shared_ptr<RequestPermOnSettingAsyncContext> asyncContext)59 static Ace::UIContent* GetUIContent(std::shared_ptr<RequestPermOnSettingAsyncContext> asyncContext)
60 {
61 if (asyncContext == nullptr) {
62 return nullptr;
63 }
64 Ace::UIContent* uiContent = nullptr;
65 if (asyncContext->uiAbilityFlag) {
66 uiContent = asyncContext->abilityContext->GetUIContent();
67 } else {
68 uiContent = asyncContext->uiExtensionContext->GetUIContent();
69 }
70 return uiContent;
71 }
72
GetContext(const napi_env & env,const napi_value & value,std::shared_ptr<RequestPermOnSettingAsyncContext> & asyncContext)73 static napi_value GetContext(
74 const napi_env &env, const napi_value &value, std::shared_ptr<RequestPermOnSettingAsyncContext>& asyncContext)
75 {
76 bool stageMode = false;
77 napi_status status = OHOS::AbilityRuntime::IsStageContext(env, value, stageMode);
78 if (status != napi_ok || !stageMode) {
79 LOGE(ATM_DOMAIN, ATM_TAG, "It is not a stage mode.");
80 return nullptr;
81 } else {
82 auto context = AbilityRuntime::GetStageModeContext(env, value);
83 if (context == nullptr) {
84 LOGE(ATM_DOMAIN, ATM_TAG, "Failed to Get application context.");
85 return nullptr;
86 }
87 asyncContext->abilityContext =
88 AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(context);
89 if (asyncContext->abilityContext != nullptr) {
90 asyncContext->uiAbilityFlag = true;
91 } else {
92 LOGW(ATM_DOMAIN, ATM_TAG, "Failed to convert to ability context.");
93 asyncContext->uiExtensionContext =
94 AbilityRuntime::Context::ConvertTo<AbilityRuntime::UIExtensionContext>(context);
95 if (asyncContext->uiExtensionContext == nullptr) {
96 LOGE(ATM_DOMAIN, ATM_TAG, "Failed to convert to ui extension context.");
97 return nullptr;
98 }
99 }
100 return WrapVoidToJS(env);
101 }
102 }
103
WrapRequestResult(const napi_env & env,const std::vector<int32_t> & pemResults)104 static napi_value WrapRequestResult(const napi_env& env, const std::vector<int32_t>& pemResults)
105 {
106 napi_value result;
107 NAPI_CALL(env, napi_create_array(env, &result));
108
109 for (size_t i = 0; i < pemResults.size(); i++) {
110 napi_value nPermissionResult = nullptr;
111 NAPI_CALL(env, napi_create_int32(env, pemResults[i], &nPermissionResult));
112 NAPI_CALL(env, napi_set_element(env, result, i, nPermissionResult));
113 }
114 return result;
115 }
116
TransferToJsErrorCode(int32_t errCode)117 static int32_t TransferToJsErrorCode(int32_t errCode)
118 {
119 int32_t jsCode = JS_OK;
120 switch (errCode) {
121 case RET_SUCCESS:
122 jsCode = JS_OK;
123 break;
124 case REQUEST_REALDY_EXIST:
125 jsCode = JS_ERROR_REQUEST_IS_ALREADY_EXIST;
126 break;
127 case PERM_NOT_BELONG_TO_SAME_GROUP:
128 jsCode = JS_ERROR_PARAM_INVALID;
129 break;
130 case PERM_IS_NOT_DECLARE:
131 jsCode = JS_ERROR_PARAM_INVALID;
132 break;
133 case ALL_PERM_GRANTED:
134 jsCode = JS_ERROR_ALL_PERM_GRANTED;
135 break;
136 case PERM_REVOKE_BY_USER:
137 jsCode = JS_ERROR_PERM_REVOKE_BY_USER;
138 break;
139 default:
140 jsCode = JS_ERROR_INNER;
141 break;
142 }
143 LOGI(ATM_DOMAIN, ATM_TAG, "dialog error(%{public}d) jsCode(%{public}d).", errCode, jsCode);
144 return jsCode;
145 }
146
PermissionResultsCallbackUI(int32_t jsCode,const std::vector<int32_t> stateList,std::shared_ptr<RequestPermOnSettingAsyncContext> & data)147 static void PermissionResultsCallbackUI(int32_t jsCode,
148 const std::vector<int32_t> stateList, std::shared_ptr<RequestPermOnSettingAsyncContext>& data)
149 {
150 auto* retCB = new (std::nothrow) PermissonOnSettingResultCallback();
151 if (retCB == nullptr) {
152 LOGE(ATM_DOMAIN, ATM_TAG, "Insufficient memory for work!");
153 return;
154 }
155
156 std::unique_ptr<PermissonOnSettingResultCallback> callbackPtr {retCB};
157 retCB->jsCode = jsCode;
158 retCB->stateList = stateList;
159 retCB->data = data;
160 auto task = [retCB]() {
161 std::shared_ptr<RequestPermOnSettingAsyncContext> asyncContext = retCB->data;
162 if (asyncContext == nullptr) {
163 delete retCB;
164 return;
165 }
166
167 int32_t result = retCB->jsCode;
168 napi_handle_scope scope = nullptr;
169 napi_open_handle_scope(asyncContext->env, &scope);
170 if (scope == nullptr) {
171 LOGE(ATM_DOMAIN, ATM_TAG, "Napi_open_handle_scope failed");
172 delete retCB;
173 return;
174 }
175 napi_value requestResult = WrapRequestResult(asyncContext->env, retCB->stateList);
176 if ((result == JS_OK) && (requestResult == nullptr)) {
177 LOGE(ATM_DOMAIN, ATM_TAG, "Wrap requestResult failed");
178 result = JS_ERROR_INNER;
179 }
180
181 ReturnPromiseResult(asyncContext->env, retCB->jsCode, asyncContext->deferred, requestResult);
182 napi_close_handle_scope(asyncContext->env, scope);
183 delete retCB;
184 };
185 if (napi_status::napi_ok != napi_send_event(data->env, task, napi_eprio_immediate)) {
186 LOGE(ATM_DOMAIN, ATM_TAG, "PermissionResultsCallbackUI: Failed to SendEvent");
187 } else {
188 callbackPtr.release();
189 }
190 }
191
CloseModalUIExtensionMainThread(std::shared_ptr<RequestPermOnSettingAsyncContext> & asyncContext,int32_t sessionId)192 static void CloseModalUIExtensionMainThread(std::shared_ptr<RequestPermOnSettingAsyncContext>& asyncContext,
193 int32_t sessionId)
194 {
195 auto task = [asyncContext, sessionId]() {
196 Ace::UIContent* uiContent = GetUIContent(asyncContext);
197 if (uiContent == nullptr) {
198 LOGE(ATM_DOMAIN, ATM_TAG, "Get ui content failed!");
199 return;
200 }
201 LOGI(ATM_DOMAIN, ATM_TAG, "Close uiextension component");
202 uiContent->CloseModalUIExtension(sessionId);
203 };
204 #ifdef EVENTHANDLER_ENABLE
205 if (asyncContext->handler_ != nullptr) {
206 asyncContext->handler_->PostSyncTask(task, "AT:CloseModalUIExtensionMainThread");
207 } else {
208 task();
209 }
210 #else
211 task();
212 #endif
213 }
214
ReleaseHandler(int32_t code)215 void PermissonOnSettingUICallback::ReleaseHandler(int32_t code)
216 {
217 {
218 std::lock_guard<std::mutex> lock(g_lockFlag);
219 if (this->reqContext_->releaseFlag) {
220 LOGW(ATM_DOMAIN, ATM_TAG, "Callback has executed.");
221 return;
222 }
223 this->reqContext_->releaseFlag = true;
224 }
225 CloseModalUIExtensionMainThread(this->reqContext_, this->sessionId_);
226 if (code == -1) {
227 this->reqContext_->errorCode = code;
228 }
229 PermissionResultsCallbackUI(
230 TransferToJsErrorCode(this->reqContext_->errorCode), this->reqContext_->stateList, this->reqContext_);
231 }
232
PermissonOnSettingUICallback(const std::shared_ptr<RequestPermOnSettingAsyncContext> & reqContext)233 PermissonOnSettingUICallback::PermissonOnSettingUICallback(
234 const std::shared_ptr<RequestPermOnSettingAsyncContext>& reqContext)
235 {
236 this->reqContext_ = reqContext;
237 }
238
~PermissonOnSettingUICallback()239 PermissonOnSettingUICallback::~PermissonOnSettingUICallback()
240 {}
241
SetSessionId(int32_t sessionId)242 void PermissonOnSettingUICallback::SetSessionId(int32_t sessionId)
243 {
244 this->sessionId_ = sessionId;
245 }
246
247 /*
248 * when UIExtensionAbility use terminateSelfWithResult
249 */
OnResult(int32_t resultCode,const AAFwk::Want & result)250 void PermissonOnSettingUICallback::OnResult(int32_t resultCode, const AAFwk::Want& result)
251 {
252 this->reqContext_->errorCode = result.GetIntParam(RESULT_ERROR_KEY, 0);
253 this->reqContext_->stateList = result.GetIntArrayParam(PERMISSION_RESULT_KEY);
254 LOGI(ATM_DOMAIN, ATM_TAG, "ResultCode is %{public}d, errorCode=%{public}d, listSize=%{public}zu",
255 resultCode, this->reqContext_->errorCode, this->reqContext_->stateList.size());
256 ReleaseHandler(0);
257 }
258
259 /*
260 * when UIExtensionAbility send message to UIExtensionComponent
261 */
OnReceive(const AAFwk::WantParams & receive)262 void PermissonOnSettingUICallback::OnReceive(const AAFwk::WantParams& receive)
263 {
264 LOGI(ATM_DOMAIN, ATM_TAG, "Called!");
265 }
266
267 /*
268 * when UIExtensionAbility disconnect or use terminate or process die
269 * releaseCode is 0 when process normal exit
270 */
OnRelease(int32_t releaseCode)271 void PermissonOnSettingUICallback::OnRelease(int32_t releaseCode)
272 {
273 LOGI(ATM_DOMAIN, ATM_TAG, "ReleaseCode is %{public}d", releaseCode);
274
275 ReleaseHandler(-1);
276 }
277
278 /*
279 * when UIExtensionComponent init or turn to background or destroy UIExtensionAbility occur error
280 */
OnError(int32_t code,const std::string & name,const std::string & message)281 void PermissonOnSettingUICallback::OnError(int32_t code, const std::string& name, const std::string& message)
282 {
283 LOGI(ATM_DOMAIN, ATM_TAG, "Code is %{public}d, name is %{public}s, message is %{public}s",
284 code, name.c_str(), message.c_str());
285
286 ReleaseHandler(-1);
287 }
288
289 /*
290 * when UIExtensionComponent connect to UIExtensionAbility, ModalUIExtensionProxy will init,
291 * UIExtensionComponent can send message to UIExtensionAbility by ModalUIExtensionProxy
292 */
OnRemoteReady(const std::shared_ptr<Ace::ModalUIExtensionProxy> & uiProxy)293 void PermissonOnSettingUICallback::OnRemoteReady(const std::shared_ptr<Ace::ModalUIExtensionProxy>& uiProxy)
294 {
295 LOGI(ATM_DOMAIN, ATM_TAG, "Connect to UIExtensionAbility successfully.");
296 }
297
298 /*
299 * when UIExtensionComponent destructed
300 */
OnDestroy()301 void PermissonOnSettingUICallback::OnDestroy()
302 {
303 LOGI(ATM_DOMAIN, ATM_TAG, "UIExtensionAbility destructed.");
304 ReleaseHandler(-1);
305 }
306
CreateUIExtensionMainThread(std::shared_ptr<RequestPermOnSettingAsyncContext> & asyncContext,const AAFwk::Want & want,const Ace::ModalUIExtensionCallbacks & uiExtensionCallbacks,const std::shared_ptr<PermissonOnSettingUICallback> & uiExtCallback)307 static void CreateUIExtensionMainThread(std::shared_ptr<RequestPermOnSettingAsyncContext>& asyncContext,
308 const AAFwk::Want& want, const Ace::ModalUIExtensionCallbacks& uiExtensionCallbacks,
309 const std::shared_ptr<PermissonOnSettingUICallback>& uiExtCallback)
310 {
311 auto task = [asyncContext, want, uiExtensionCallbacks, uiExtCallback]() {
312 Ace::UIContent* uiContent = GetUIContent(asyncContext);
313 if (uiContent == nullptr) {
314 LOGE(ATM_DOMAIN, ATM_TAG, "Failed to get ui content!");
315 asyncContext->result = RET_FAILED;
316 return;
317 }
318
319 Ace::ModalUIExtensionConfig config;
320 config.isProhibitBack = true;
321 int32_t sessionId = uiContent->CreateModalUIExtension(want, uiExtensionCallbacks, config);
322 LOGI(ATM_DOMAIN, ATM_TAG, "Create end, sessionId: %{public}d, tokenId: %{public}d.",
323 sessionId, asyncContext->tokenId);
324 if (sessionId == 0) {
325 LOGE(ATM_DOMAIN, ATM_TAG, "Failed to create component, sessionId is 0.");
326 asyncContext->result = RET_FAILED;
327 return;
328 }
329 uiExtCallback->SetSessionId(sessionId);
330 };
331 #ifdef EVENTHANDLER_ENABLE
332 if (asyncContext->handler_ != nullptr) {
333 asyncContext->handler_->PostSyncTask(task, "AT:CreateUIExtensionMainThread");
334 } else {
335 task();
336 }
337 #else
338 task();
339 #endif
340 }
341
CreateUIExtension(const Want & want,std::shared_ptr<RequestPermOnSettingAsyncContext> asyncContext)342 static int32_t CreateUIExtension(const Want &want, std::shared_ptr<RequestPermOnSettingAsyncContext> asyncContext)
343 {
344 auto uiExtCallback = std::make_shared<PermissonOnSettingUICallback>(asyncContext);
345 Ace::ModalUIExtensionCallbacks uiExtensionCallbacks = {
346 [uiExtCallback](int32_t releaseCode) {
347 uiExtCallback->OnRelease(releaseCode);
348 },
349 [uiExtCallback](int32_t resultCode, const AAFwk::Want &result) {
350 uiExtCallback->OnResult(resultCode, result);
351 },
352 [uiExtCallback](const AAFwk::WantParams &receive) {
353 uiExtCallback->OnReceive(receive);
354 },
355 [uiExtCallback](int32_t code, const std::string &name, [[maybe_unused]] const std::string &message) {
356 uiExtCallback->OnError(code, name, name);
357 },
358 [uiExtCallback](const std::shared_ptr<Ace::ModalUIExtensionProxy> &uiProxy) {
359 uiExtCallback->OnRemoteReady(uiProxy);
360 },
361 [uiExtCallback]() {
362 uiExtCallback->OnDestroy();
363 },
364 };
365
366 CreateUIExtensionMainThread(asyncContext, want, uiExtensionCallbacks, uiExtCallback);
367 if (asyncContext->result == RET_FAILED) {
368 return RET_FAILED;
369 }
370 return JS_OK;
371 }
372
StartUIExtension(std::shared_ptr<RequestPermOnSettingAsyncContext> asyncContext)373 static int32_t StartUIExtension(std::shared_ptr<RequestPermOnSettingAsyncContext> asyncContext)
374 {
375 AAFwk::Want want;
376 AccessTokenKit::GetPermissionManagerInfo(asyncContext->info);
377 LOGI(ATM_DOMAIN, ATM_TAG, "bundleName: %{public}s, permStateAbilityName: %{public}s.",
378 asyncContext->info.grantBundleName.c_str(), asyncContext->info.permStateAbilityName.c_str());
379 want.SetElementName(asyncContext->info.grantBundleName, asyncContext->info.permStateAbilityName);
380 want.SetParam(PERMISSION_KEY, asyncContext->permissionList);
381 want.SetParam(EXTENSION_TYPE_KEY, UI_EXTENSION_TYPE);
382 return CreateUIExtension(want, asyncContext);
383 }
384
RequestPermissionOnSetting(napi_env env,napi_callback_info info)385 napi_value NapiRequestPermissionOnSetting::RequestPermissionOnSetting(napi_env env, napi_callback_info info)
386 {
387 LOGD(ATM_DOMAIN, ATM_TAG, "RequestPermissionOnSetting begin.");
388 // use handle to protect asyncContext
389 std::shared_ptr<RequestPermOnSettingAsyncContext> asyncContext =
390 std::make_shared<RequestPermOnSettingAsyncContext>(env);
391
392 if (!ParseRequestPermissionOnSetting(env, info, asyncContext)) {
393 return nullptr;
394 }
395 auto asyncContextHandle = std::make_unique<RequestOnSettingAsyncContextHandle>(asyncContext);
396 napi_value result = nullptr;
397 if (asyncContextHandle->asyncContextPtr->callbackRef == nullptr) {
398 NAPI_CALL(env, napi_create_promise(env, &(asyncContextHandle->asyncContextPtr->deferred), &result));
399 } else {
400 NAPI_CALL(env, napi_get_undefined(env, &result));
401 }
402
403 napi_value resource = nullptr; // resource name
404 NAPI_CALL(env, napi_create_string_utf8(env, "RequestPermissionOnSetting", NAPI_AUTO_LENGTH, &resource));
405 NAPI_CALL(env, napi_create_async_work(
406 env, nullptr, resource, RequestPermissionOnSettingExecute, RequestPermissionOnSettingComplete,
407 reinterpret_cast<void *>(asyncContextHandle.get()), &(asyncContextHandle->asyncContextPtr->work)));
408
409 NAPI_CALL(env,
410 napi_queue_async_work_with_qos(env, asyncContextHandle->asyncContextPtr->work, napi_qos_user_initiated));
411
412 LOGD(ATM_DOMAIN, ATM_TAG, "RequestPermissionOnSetting end.");
413 asyncContextHandle.release();
414 return result;
415 }
416
ParseRequestPermissionOnSetting(const napi_env & env,const napi_callback_info & cbInfo,std::shared_ptr<RequestPermOnSettingAsyncContext> & asyncContext)417 bool NapiRequestPermissionOnSetting::ParseRequestPermissionOnSetting(const napi_env& env,
418 const napi_callback_info& cbInfo, std::shared_ptr<RequestPermOnSettingAsyncContext>& asyncContext)
419 {
420 size_t argc = NapiContextCommon::MAX_PARAMS_TWO;
421 napi_value argv[NapiContextCommon::MAX_PARAMS_TWO] = { nullptr };
422 napi_value thisVar = nullptr;
423
424 if (napi_get_cb_info(env, cbInfo, &argc, argv, &thisVar, nullptr) != napi_ok) {
425 LOGE(ATM_DOMAIN, ATM_TAG, "Napi_get_cb_info failed");
426 return false;
427 }
428 if (argc < NapiContextCommon::MAX_PARAMS_TWO - 1) {
429 NAPI_CALL_BASE(env, napi_throw(env, GenerateBusinessError(env,
430 JsErrorCode::JS_ERROR_PARAM_ILLEGAL, "Parameter is missing.")), false);
431 return false;
432 }
433 asyncContext->env = env;
434 std::string errMsg;
435
436 // argv[0] : context : AbilityContext
437 if (GetContext(env, argv[0], asyncContext) == nullptr) {
438 errMsg = GetParamErrorMsg("context", "UIAbility or UIExtension Context");
439 NAPI_CALL_BASE(
440 env, napi_throw(env, GenerateBusinessError(env, JsErrorCode::JS_ERROR_PARAM_ILLEGAL, errMsg)), false);
441 return false;
442 }
443 LOGI(ATM_DOMAIN, ATM_TAG, "AsyncContext.uiAbilityFlag is: %{public}d.", asyncContext->uiAbilityFlag);
444
445 // argv[1] : permissionList
446 if (!ParseStringArray(env, argv[1], asyncContext->permissionList) ||
447 (asyncContext->permissionList.empty())) {
448 errMsg = GetParamErrorMsg("permissionList", "Array<Permissions>");
449 NAPI_CALL_BASE(
450 env, napi_throw(env, GenerateBusinessError(env, JsErrorCode::JS_ERROR_PARAM_ILLEGAL, errMsg)), false);
451 return false;
452 }
453 #ifdef EVENTHANDLER_ENABLE
454 asyncContext->handler_ = std::make_shared<AppExecFwk::EventHandler>(AppExecFwk::EventRunner::GetMainEventRunner());
455 #endif
456 return true;
457 }
458
RequestPermissionOnSettingExecute(napi_env env,void * data)459 void NapiRequestPermissionOnSetting::RequestPermissionOnSettingExecute(napi_env env, void* data)
460 {
461 // asyncContext release in complete
462 RequestOnSettingAsyncContextHandle* asyncContextHandle =
463 reinterpret_cast<RequestOnSettingAsyncContextHandle*>(data);
464 if ((asyncContextHandle == nullptr) || (asyncContextHandle->asyncContextPtr == nullptr)) {
465 return;
466 }
467 if (asyncContextHandle->asyncContextPtr->uiAbilityFlag) {
468 if ((asyncContextHandle->asyncContextPtr->abilityContext == nullptr) ||
469 (asyncContextHandle->asyncContextPtr->abilityContext->GetApplicationInfo() == nullptr)) {
470 return;
471 }
472 asyncContextHandle->asyncContextPtr->tokenId =
473 asyncContextHandle->asyncContextPtr->abilityContext->GetApplicationInfo()->accessTokenId;
474 } else {
475 if ((asyncContextHandle->asyncContextPtr->uiExtensionContext == nullptr) ||
476 (asyncContextHandle->asyncContextPtr->uiExtensionContext->GetApplicationInfo() == nullptr)) {
477 return;
478 }
479 asyncContextHandle->asyncContextPtr->tokenId =
480 asyncContextHandle->asyncContextPtr->uiExtensionContext->GetApplicationInfo()->accessTokenId;
481 }
482 static AccessTokenID currToken = static_cast<AccessTokenID>(GetSelfTokenID());
483 if (asyncContextHandle->asyncContextPtr->tokenId != currToken) {
484 LOGE(ATM_DOMAIN, ATM_TAG,
485 "The context(token=%{public}d) is not belong to the current application(currToken=%{public}d).",
486 asyncContextHandle->asyncContextPtr->tokenId, currToken);
487 asyncContextHandle->asyncContextPtr->result = ERR_PARAM_INVALID;
488 return;
489 }
490
491 LOGI(ATM_DOMAIN, ATM_TAG, "Start to pop ui extension dialog");
492 StartUIExtension(asyncContextHandle->asyncContextPtr);
493 if (asyncContextHandle->asyncContextPtr->result != JsErrorCode::JS_OK) {
494 LOGW(ATM_DOMAIN, ATM_TAG, "Failed to pop uiextension dialog.");
495 }
496 }
497
RequestPermissionOnSettingComplete(napi_env env,napi_status status,void * data)498 void NapiRequestPermissionOnSetting::RequestPermissionOnSettingComplete(napi_env env, napi_status status, void* data)
499 {
500 LOGD(ATM_DOMAIN, ATM_TAG, "RequestPermissionOnSettingComplete begin.");
501 RequestOnSettingAsyncContextHandle* asyncContextHandle =
502 reinterpret_cast<RequestOnSettingAsyncContextHandle*>(data);
503 if (asyncContextHandle == nullptr || asyncContextHandle->asyncContextPtr == nullptr) {
504 return;
505 }
506 std::unique_ptr<RequestOnSettingAsyncContextHandle> callbackPtr {asyncContextHandle};
507
508 // need pop dialog
509 if (asyncContextHandle->asyncContextPtr->result == RET_SUCCESS) {
510 return;
511 }
512 // return error
513 if (asyncContextHandle->asyncContextPtr->deferred != nullptr) {
514 int32_t jsCode = NapiContextCommon::GetJsErrorCode(asyncContextHandle->asyncContextPtr->result);
515 napi_value businessError = GenerateBusinessError(env, jsCode, GetErrorMessage(jsCode));
516 NAPI_CALL_RETURN_VOID(env,
517 napi_reject_deferred(env, asyncContextHandle->asyncContextPtr->deferred, businessError));
518 }
519 }
520 } // namespace AccessToken
521 } // namespace Security
522 } // namespace OHOS