• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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