From 5d0f1ea02b5a2379f0769dbe0fa7b4bef3c4bd49 Mon Sep 17 00:00:00 2001 From: GaoShuo Date: Tue, 12 Aug 2025 09:41:35 +0800 Subject: [PATCH 1/2] tmp1 --- .../ets/@ohos.abilityAccessCtrl.ets | 64 ++++++ .../ets/ani/accesstoken/include/ani_common.h | 2 + .../include/ani_request_permission.h | 5 + .../ani_request_permission_on_setting.h | 3 + .../src/ani_ability_access_ctrl.cpp | 2 + .../ets/ani/accesstoken/src/ani_common.cpp | 27 +++ .../src/ani_request_permission.cpp | 189 +++++++++++++++++- .../src/ani_request_permission_on_setting.cpp | 6 +- frameworks/ets/ani/common/include/ani_utils.h | 2 +- 9 files changed, 290 insertions(+), 10 deletions(-) diff --git a/frameworks/ets/ani/accesstoken/ets/@ohos.abilityAccessCtrl.ets b/frameworks/ets/ani/accesstoken/ets/@ohos.abilityAccessCtrl.ets index 8de915f7f..9c5adfc3e 100644 --- a/frameworks/ets/ani/accesstoken/ets/@ohos.abilityAccessCtrl.ets +++ b/frameworks/ets/ani/accesstoken/ets/@ohos.abilityAccessCtrl.ets @@ -103,11 +103,35 @@ export default namespace abilityAccessCtrl { } } + function validateRequestParams(context: Context, windowId: number, permissionList: Array): void { + if ((typeof context === "undefined") || (context == null)) { + let err = new BusinessError(); + err.code = STSErrorCode.STS_ERROR_PARAM_ILLEGAL as int; + err.data = PARAM_ERROR_MSG("context", "UIAbility or UIExtension Context"); + throw err; + } + if ((typeof windowId !== "number") || (windowId < 0)) { + let err = new BusinessError(); + err.code = STSErrorCode.STS_ERROR_PARAM_ILLEGAL as int; + err.data = PARAM_ERROR_MSG("windowId", "number >= 0"); + throw err; + } + if (typeof permissionList !== "object" || !Array.isArray(permissionList) || + permissionList.length == 0 || typeof permissionList[0] !== "string") { + let err = new BusinessError(); + err.code = STSErrorCode.STS_ERROR_PARAM_ILLEGAL as int; + err.data = PARAM_ERROR_MSG("permissionList", "Array"); + throw err; + } + } + native function createAtManager(): AtManager; interface AtManager { checkAccessTokenExecute(tokenID: int, permissionName: Permissions): int; requestPermissionsFromUserExecute(context: Context, permissionList: Array, callback: AsyncCallbackWrapper): void; + requestPermissionsFromUserWithWindowIdExecute(context: Context, windowId: number, permissionList: Array, + callback: AsyncCallbackWrapper): void; requestPermissionOnSettingExecute(context: Context, permissionList: Array, callback: AsyncCallbackWrapper>): void; requestGlobalSwitchExecute( @@ -134,8 +158,15 @@ export default namespace abilityAccessCtrl { requestCallback: AsyncCallback): void; requestPermissionsFromUser( context: Context, permissionList: Array): Promise; + requestPermissionsFromUserWithWindowId( + context: Context, windowId: number, permissionList: Array, + requestCallback: AsyncCallback): void; + requestPermissionsFromUserWithWindowId( + context: Context, windowId: number, permissionList: Array): Promise; requestPermissionOnSetting( context: Context, permissionList: Array): Promise>; + requestPermissionOnSettingWithWindowId( + context: Context, windowId: number, permissionList: Array): Promise>; requestGlobalSwitch(context: Context, type: SwitchType): Promise; grantUserGrantedPermission( tokenID: int, @@ -172,6 +203,8 @@ export default namespace abilityAccessCtrl { native checkAccessTokenExecute(tokenID: int, permissionName: Permissions): int; native requestPermissionsFromUserExecute(context: Context, permissionList: Array, callback: AsyncCallbackWrapper): void; + native requestPermissionsFromUserWithWindowIdExecute(context: Context, windowId: number, permissionList: Array, + callback: AsyncCallbackWrapper): void; native requestPermissionOnSettingExecute(context: Context, permissionList: Array, callback: AsyncCallbackWrapper>): void; native requestGlobalSwitchExecute( @@ -262,6 +295,37 @@ export default namespace abilityAccessCtrl { return p; } + requestPermissionsFromUserWithWindowId(context: Context, windowId: number, permissionList: Array, + requestCallback: AsyncCallback): void { + validateRequestParams(context, windowId, permissionList); + let callbackWrap = new AsyncCallbackWrapper(requestCallback); + taskpool.execute((): void => { + new AtManagerInner().requestPermissionsFromUserWithWindowIdExecute(context, windowId, permissionList, callbackWrap); + }); + } + + requestPermissionsFromUserWithWindowId(context: Context, windowId: number, permissionList: Array): + Promise { + validateRequestParams(context, windowId, permissionList); + let p: Promise = new Promise(( + resolve: (v: PermissionRequestResult) => void, reject: (error: BusinessError) => void) => { + let callbackWrap = new AsyncCallbackWrapper(( + err: BusinessError | null, data: PermissionRequestResult | undefined) => { + if (err?.code == 0) { + if (data !== undefined) { + resolve(data); + } + } else { + reject(err as BusinessError); + } + }); + taskpool.execute((): void => { + new AtManagerInner().requestPermissionsFromUserWithWindowIdExecute(context, windowId, permissionList, callbackWrap); + }); + }); + return p; + } + requestPermissionOnSetting(context: Context, permissionList: Array): Promise> { validateRequestParams(context, permissionList); let p: Promise> = new Promise>(( diff --git a/frameworks/ets/ani/accesstoken/include/ani_common.h b/frameworks/ets/ani/accesstoken/include/ani_common.h index e419b3516..39508be3c 100644 --- a/frameworks/ets/ani/accesstoken/include/ani_common.h +++ b/frameworks/ets/ani/accesstoken/include/ani_common.h @@ -26,6 +26,8 @@ namespace OHOS { namespace Security { namespace AccessToken { bool ExecuteAsyncCallback(ani_env* env, ani_object callback, ani_object error, ani_object result); +OHOS::Ace::UIContent* GetUIContent(const std::shared_ptr& abilityContext, + std::shared_ptr& uiExtensionContext, uint32_t windowId, bool isWithWindowId, bool uiAbilityFlag); OHOS::Ace::UIContent* GetUIContent(const std::shared_ptr& abilityContext, std::shared_ptr& uiExtensionContext, bool uiAbilityFlag); } // namespace AccessToken diff --git a/frameworks/ets/ani/accesstoken/include/ani_request_permission.h b/frameworks/ets/ani/accesstoken/include/ani_request_permission.h index 7d4da55ac..a0dd6d682 100644 --- a/frameworks/ets/ani/accesstoken/include/ani_request_permission.h +++ b/frameworks/ets/ani/accesstoken/include/ani_request_permission.h @@ -40,6 +40,7 @@ struct RequestAsyncContext { bool needDynamicRequest = true; AtmResult result; int32_t instanceId = -1; + uint32_t windowId = 0; std::vector permissionList; std::vector grantResults; std::vector permissionsState; @@ -49,6 +50,7 @@ struct RequestAsyncContext { Security::AccessToken::PermissionGrantInfo info; std::shared_ptr abilityContext = nullptr; std::shared_ptr uiExtensionContext = nullptr; + bool isWithWindowId = false; bool uiAbilityFlag = false; bool uiExtensionFlag = false; bool uiContentFlag = false; @@ -115,6 +117,9 @@ struct ResultCallback { void RequestPermissionsFromUserExecute([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object object, ani_object aniContext, ani_array_ref permissionList, ani_object callback); +void RequestPermissionsFromUserWithWindowIdExecute([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object object, + ani_object aniContext, ani_ref windowId, ani_array_ref permissionList, ani_object callback); + class RegisterPermStateChangeScopePtr : public std::enable_shared_from_this, public PermStateChangeCallbackCustomize { public: diff --git a/frameworks/ets/ani/accesstoken/include/ani_request_permission_on_setting.h b/frameworks/ets/ani/accesstoken/include/ani_request_permission_on_setting.h index 5d73f5817..f744ed58b 100644 --- a/frameworks/ets/ani/accesstoken/include/ani_request_permission_on_setting.h +++ b/frameworks/ets/ani/accesstoken/include/ani_request_permission_on_setting.h @@ -20,6 +20,7 @@ #include "ani_common.h" #include "ani_error.h" #include "ani_utils.h" +#include #ifdef EVENTHANDLER_ENABLE #include "event_handler.h" #include "event_queue.h" @@ -36,6 +37,8 @@ struct RequestPermOnSettingAsyncContext { PermissionGrantInfo info; int32_t instanceId = -1; + uint32_t windowId = 0; + bool isWithWindowId = false; bool isDynamic = true; std::vector permissionList; ani_object requestResult = nullptr; diff --git a/frameworks/ets/ani/accesstoken/src/ani_ability_access_ctrl.cpp b/frameworks/ets/ani/accesstoken/src/ani_ability_access_ctrl.cpp index 870f6c7e0..f5d018e97 100644 --- a/frameworks/ets/ani/accesstoken/src/ani_ability_access_ctrl.cpp +++ b/frameworks/ets/ani/accesstoken/src/ani_ability_access_ctrl.cpp @@ -839,6 +839,8 @@ void InitAbilityCtrlFunction(ani_env *env) ani_native_function { "checkAccessTokenExecute", nullptr, reinterpret_cast(CheckAccessTokenExecute) }, ani_native_function { "requestPermissionsFromUserExecute", nullptr, reinterpret_cast(RequestPermissionsFromUserExecute) }, + ani_native_function { "requestPermissionsFromUserWithWindowIdExecute", + nullptr, reinterpret_cast(RequestPermissionsFromUserWithWindowIdExecute) }, ani_native_function { "requestPermissionOnSettingExecute", nullptr, reinterpret_cast(RequestPermissionOnSettingExecute) }, ani_native_function {"requestGlobalSwitchExecute", diff --git a/frameworks/ets/ani/accesstoken/src/ani_common.cpp b/frameworks/ets/ani/accesstoken/src/ani_common.cpp index 8631bf74b..bf0bdbf2f 100644 --- a/frameworks/ets/ani/accesstoken/src/ani_common.cpp +++ b/frameworks/ets/ani/accesstoken/src/ani_common.cpp @@ -13,8 +13,10 @@ * limitations under the License. */ #include "ani_common.h" + #include "accesstoken_common_log.h" #include +#include "window.h" namespace OHOS { namespace Security { namespace AccessToken { @@ -51,6 +53,31 @@ bool ExecuteAsyncCallback(ani_env* env, ani_object callback, ani_object error, a return true; } +OHOS::Ace::UIContent* GetUIContent(const std::shared_ptr& abilityContext, + std::shared_ptr& uiExtensionContext, uint32_t windowId, bool isWithWindowId, bool uiAbilityFlag) +{ + OHOS::Ace::UIContent* uiContent = nullptr; + if (isWithWindowId) { + sptr window = OHOS::Rosen::Window::GetWindowWithId(windowId); + if(window == nullptr) { + LOGE(ATM_DOMAIN, ATM_TAG, "Get window with id %{public}d failed", windowId); + return nullptr; + } + uiContent = window->GetUIContent(); + } else if (uiAbilityFlag) { + if (abilityContext == nullptr) { + return nullptr; + } + uiContent = abilityContext->GetUIContent(); + } else { + if (uiExtensionContext == nullptr) { + return nullptr; + } + uiContent = uiExtensionContext->GetUIContent(); + } + return uiContent; +} + OHOS::Ace::UIContent* GetUIContent(const std::shared_ptr& abilityContext, std::shared_ptr& uiExtensionContext, bool uiAbilityFlag) { diff --git a/frameworks/ets/ani/accesstoken/src/ani_request_permission.cpp b/frameworks/ets/ani/accesstoken/src/ani_request_permission.cpp index 6e4ac4ca1..5fd976b96 100644 --- a/frameworks/ets/ani/accesstoken/src/ani_request_permission.cpp +++ b/frameworks/ets/ani/accesstoken/src/ani_request_permission.cpp @@ -25,6 +25,7 @@ #include "hisysevent.h" #include "token_setproc.h" #include "want.h" +#include "window.h" namespace OHOS { namespace Security { @@ -188,7 +189,7 @@ static void CreateUIExtensionMainThread(std::shared_ptr& as { auto task = [asyncContext, want, uiExtensionCallbacks, uiExtCallback]() { OHOS::Ace::UIContent* uiContent = GetUIContent(asyncContext->abilityContext, - asyncContext->uiExtensionContext, asyncContext->uiAbilityFlag); + asyncContext->uiExtensionContext, asyncContext->windowId, asyncContext->isWithWindowId, asyncContext->uiAbilityFlag); if (uiContent == nullptr) { LOGE(ATM_DOMAIN, ATM_TAG, "Failed to get ui content!"); asyncContext->result.errorCode = AccessToken::RET_FAILED; @@ -219,7 +220,10 @@ static void CreateUIExtensionMainThread(std::shared_ptr& as } static void CreateServiceExtension(std::shared_ptr& asyncContext) -{ +{ + if ((asyncContext == nullptr) || (asyncContext->abilityContext == nullptr)) { + return; + } if (!asyncContext->uiAbilityFlag) { LOGE(ATM_DOMAIN, ATM_TAG, "UIExtension ability can not pop service ablility window!"); asyncContext->needDynamicRequest = false; @@ -256,6 +260,59 @@ static void CreateServiceExtension(std::shared_ptr& asyncCo asyncContext->tokenId, asyncContext->permissionList.size()); } +static void CreateServiceExtensionWithWindowId(std::shared_ptr& asyncContext) +{ + if ((asyncContext == nullptr) || (asyncContext->abilityContext == nullptr)) { + return; + } + if (!asyncContext->uiAbilityFlag) { + LOGE(ATM_DOMAIN, ATM_TAG, "UIExtension ability can not pop service ablility window!"); + asyncContext->needDynamicRequest = false; + asyncContext->result.errorCode = RET_FAILED; + return; + } + OHOS::sptr remoteObject = new (std::nothrow) AuthorizationResult(asyncContext); + if (remoteObject == nullptr) { + LOGE(ATM_DOMAIN, ATM_TAG, "Failed to Create window!"); + asyncContext->needDynamicRequest = false; + asyncContext->result.errorCode = RET_FAILED; + return; + } + OHOS::AAFwk::Want want; + want.SetElementName(asyncContext->info.grantBundleName, asyncContext->info.grantServiceAbilityName); + want.SetParam(PERMISSION_KEY, asyncContext->permissionList); + want.SetParam(STATE_KEY, asyncContext->permissionsState); + want.SetParam(TOKEN_KEY, asyncContext->abilityContext->GetToken()); + want.SetParam(CALLBACK_KEY, remoteObject); + + sptr window = OHOS::Rosen::Window::GetWindowWithId(asyncContext->windowId); + + if (window == nullptr) { + LOGE(ATM_DOMAIN, ATM_TAG, "GetWindowWithId failed, windowId: %{public}d", asyncContext->windowId); + asyncContext->needDynamicRequest = false; + asyncContext->result.errorCode = RET_FAILED; + return; + } + + Rosen::Rect windowRect = window->GetRect(); + + int32_t left = windowRect.posX_; + int32_t top = windowRect.posY_; + int32_t width = windowRect.width_; + int32_t height = windowRect.height_; + + want.SetParam(WINDOW_RECTANGLE_LEFT_KEY, left); + want.SetParam(WINDOW_RECTANGLE_TOP_KEY, top); + want.SetParam(WINDOW_RECTANGLE_WIDTH_KEY, width); + want.SetParam(WINDOW_RECTANGLE_HEIGHT_KEY, height); + want.SetParam(REQUEST_TOKEN_KEY, asyncContext->abilityContext->GetToken()); + int32_t ret = OHOS::AAFwk::AbilityManagerClient::GetInstance()->RequestDialogService( + want, asyncContext->abilityContext->GetToken()); + + LOGI(ATM_DOMAIN, ATM_TAG, "Request end, ret: %{public}d, tokenId: %{public}d, permNum: %{public}zu。", ret, + asyncContext->tokenId, asyncContext->permissionList.size()); +} + static void CreateUIExtension(std::shared_ptr& asyncContext) { OHOS::AAFwk::Want want; @@ -285,7 +342,7 @@ static void GetInstanceId(std::shared_ptr& asyncContext) { auto task = [asyncContext]() { OHOS::Ace::UIContent* uiContent = GetUIContent(asyncContext->abilityContext, - asyncContext->uiExtensionContext, asyncContext->uiAbilityFlag); + asyncContext->uiExtensionContext, asyncContext->windowId, asyncContext->isWithWindowId, asyncContext->uiAbilityFlag); if (uiContent == nullptr) { LOGE(ATM_DOMAIN, ATM_TAG, "Failed to get ui content failed!"); return; @@ -408,6 +465,47 @@ static void RequestPermissionsFromUserProcess(std::shared_ptr& asyncContext) +{ + if (!IsDynamicRequest(asyncContext)) { + LOGE(ATM_DOMAIN, ATM_TAG, "It does not need to request permission."); + asyncContext->needDynamicRequest = false; + if ((asyncContext->permissionsState.empty()) && (asyncContext->result.errorCode == RET_SUCCESS)) { + LOGE(ATM_DOMAIN, ATM_TAG, "Empty GrantResults."); + asyncContext->result.errorCode = RET_FAILED; + } + return; + } + + GetInstanceId(asyncContext); + if (asyncContext->info.grantBundleName == ORI_PERMISSION_MANAGER_BUNDLE_NAME) { + LOGI(ATM_DOMAIN, ATM_TAG, + "Pop service extension dialog, uiContentFlag=%{public}d.", asyncContext->uiContentFlag); + if (asyncContext->uiContentFlag) { + RequestAsyncInstanceControl::AddCallbackByInstanceId(asyncContext); + } else { + CreateServiceExtensionWithWindowId(asyncContext); + } + } else if (asyncContext->instanceId == -1) { + LOGE(ATM_DOMAIN, ATM_TAG, "Pop service extension dialog, instanceId is -1."); + CreateServiceExtensionWithWindowId(asyncContext); + (void)HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::ACCESS_TOKEN, "REQUEST_PERMISSIONS_FROM_USER", + HiviewDFX::HiSysEvent::EventType::BEHAVIOR, "BUNDLENAME", asyncContext->bundleName.c_str(), + "UIEXTENSION_FLAG", false); + } else { + LOGI(ATM_DOMAIN, ATM_TAG, "Pop ui extension dialog."); + asyncContext->uiExtensionFlag = true; + RequestAsyncInstanceControl::AddCallbackByInstanceId(asyncContext); + (void)HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::ACCESS_TOKEN, "REQUEST_PERMISSIONS_FROM_USER", + HiviewDFX::HiSysEvent::EventType::BEHAVIOR, "BUNDLENAME", asyncContext->bundleName, "UIEXTENSION_FLAG", + false); + if (!asyncContext->uiExtensionFlag) { + LOGW(ATM_DOMAIN, ATM_TAG, "Pop uiextension dialog fail, start to pop service extension dialog."); + RequestAsyncInstanceControl::AddCallbackByInstanceId(asyncContext); + } + } +} + static bool ParseRequestPermissionFromUser(ani_env* env, ani_object aniContext, ani_array_ref aniPermissionList, ani_object callback, std::shared_ptr& asyncContext) { @@ -439,6 +537,43 @@ static bool ParseRequestPermissionFromUser(ani_env* env, ani_object aniContext, return true; } +static bool ParseRequestPermissionFromUserWithWindowId(ani_env* env, ani_object aniContext, ani_ref windowId, ani_array_ref aniPermissionList, + ani_object callback, std::shared_ptr& asyncContext) +{ + ani_vm* vm; + ani_status status = env->GetVM(&vm); + if (status != ANI_OK) { + LOGE(ATM_DOMAIN, ATM_TAG, "Failed to GetVM, error=%{public}d.", static_cast(status)); + return false; + } + asyncContext->vm = vm; + asyncContext->env = env; + asyncContext->callback = callback; + asyncContext->threadId = std::this_thread::get_id(); + + status = ConvertContext(env, aniContext, asyncContext); + if (status != ANI_OK) { + LOGE(ATM_DOMAIN, ATM_TAG, "Failed to ConvertContext, error=%{public}d.", static_cast(status)); + BusinessErrorAni::ThrowParameterTypeError(env, STS_ERROR_PARAM_ILLEGAL, + GetParamErrorMsg("context", "UIAbility or UIExtension Context")); + return false; + } + if (!AniParseUint32(env, windowId, asyncContext->windowId)) { + LOGE(ATM_DOMAIN, ATM_TAG, "Failed to ParseUint32."); + BusinessErrorAni::ThrowParameterTypeError(env, STS_ERROR_PARAM_ILLEGAL, + GetParamErrorMsg("windowId", "uint32_t")); + return false; + } + asyncContext->permissionList = ParseAniStringVector(env, aniPermissionList); + if (!AniParseCallback(env, reinterpret_cast(callback), asyncContext->callbackRef)) { + return false; + } +#ifdef EVENTHANDLER_ENABLE + asyncContext->handler_ = std::make_shared(AppExecFwk::EventRunner::GetMainEventRunner()); +#endif + return true; +} + void RequestPermissionsFromUserExecute([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object object, ani_object aniContext, ani_array_ref aniPermissionList, ani_object callback) { @@ -478,11 +613,51 @@ void RequestPermissionsFromUserExecute([[maybe_unused]] ani_env* env, [[maybe_un asyncContext->uiExtensionFlag, asyncContext->uiContentFlag, asyncContext->uiAbilityFlag); } +void RequestPermissionsFromUserWithWindowIdExecute([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object object, + ani_object aniContext, ani_ref windowId, ani_array_ref aniPermissionList, ani_object callback) +{ + if (env == nullptr || windowId == nullptr || aniPermissionList == nullptr || callback == nullptr) { + LOGE(ATM_DOMAIN, ATM_TAG, "Env or windowId or aniPermissionList or callback is null."); + return; + } + std::shared_ptr asyncContext = std::make_shared(); + if (!ParseRequestPermissionFromUserWithWindowId(env, aniContext, windowId, aniPermissionList, callback, asyncContext)) { + return; + } + + asyncContext->isWithWindowId = true; + static AccessTokenID selfTokenID = static_cast(GetSelfTokenID()); + if (selfTokenID != asyncContext->tokenId) { + LOGE(ATM_DOMAIN, ATM_TAG, + "The context tokenID: %{public}d, selfTokenID: %{public}d.", asyncContext->tokenId, selfTokenID); + + ani_ref nullRef = nullptr; + env->GetNull(&nullRef); + ani_object result = reinterpret_cast(nullRef); + ani_object error = BusinessErrorAni::CreateError(env, STS_ERROR_INNER, GetErrorMessage(STS_ERROR_INNER, + "The specified context does not belong to the current application.")); + ExecuteAsyncCallback(env, callback, error, result); + return; + } + RequestPermissionsFromUserWithWindowIdProcess(asyncContext); + if (asyncContext->needDynamicRequest) { + return; + } + + int32_t stsCode = BusinessErrorAni::GetStsErrorCode(asyncContext->result.errorCode); + ani_object error = BusinessErrorAni::CreateError( + env, stsCode, GetErrorMessage(stsCode, asyncContext->result.errorMsg)); + ani_object result = WrapResult(env, asyncContext); + ExecuteAsyncCallback(env, callback, error, result); + LOGI(ATM_DOMAIN, ATM_TAG, "UiExtensionFlag: %{public}d, uiContentFlag: %{public}d, uiAbilityFlag: %{public}d.", + asyncContext->uiExtensionFlag, asyncContext->uiContentFlag, asyncContext->uiAbilityFlag); +} + static void CloseModalUIExtensionMainThread(std::shared_ptr& asyncContext, int32_t sessionId) { auto task = [asyncContext, sessionId]() { - Ace::UIContent* uiContent = GetUIContent(asyncContext->abilityContext, - asyncContext->uiExtensionContext, asyncContext->uiAbilityFlag); + OHOS::Ace::UIContent* uiContent = GetUIContent(asyncContext->abilityContext, + asyncContext->uiExtensionContext, asyncContext->windowId, asyncContext->isWithWindowId, asyncContext->uiAbilityFlag); if (uiContent == nullptr) { LOGE(ATM_DOMAIN, ATM_TAG, "Failed to get ui content!"); asyncContext->result.errorCode = RET_FAILED; @@ -562,6 +737,8 @@ void RequestAsyncInstanceControl::AddCallbackByInstanceId(std::shared_ptruiExtensionFlag) { CreateUIExtension(asyncContext); + } else if(asyncContext->isWithWindowId) { + CreateServiceExtensionWithWindowId(asyncContext); } else { CreateServiceExtension(asyncContext); } @@ -654,7 +831,7 @@ void AuthorizationResult::WindowShownCallback() return; } OHOS::Ace::UIContent* uiContent = GetUIContent(asyncContext->abilityContext, - asyncContext->uiExtensionContext, asyncContext->uiAbilityFlag); + asyncContext->uiExtensionContext, asyncContext->windowId, asyncContext->isWithWindowId, asyncContext->uiAbilityFlag); if ((uiContent == nullptr) || !(asyncContext->uiContentFlag)) { return; } diff --git a/frameworks/ets/ani/accesstoken/src/ani_request_permission_on_setting.cpp b/frameworks/ets/ani/accesstoken/src/ani_request_permission_on_setting.cpp index d10008ac0..da2e07be9 100644 --- a/frameworks/ets/ani/accesstoken/src/ani_request_permission_on_setting.cpp +++ b/frameworks/ets/ani/accesstoken/src/ani_request_permission_on_setting.cpp @@ -244,7 +244,7 @@ static void CloseSettingModalUIExtensionMainThread(std::shared_ptrabilityContext, - asyncContext->uiExtensionContext, asyncContext->uiAbilityFlag); + asyncContext->uiExtensionContext, asyncContext->windowId, asyncContext->isWithWindowId, asyncContext->uiAbilityFlag); if (uiContent == nullptr) { LOGE(ATM_DOMAIN, ATM_TAG, "Failed to get ui content!"); asyncContext->result.errorCode = RET_FAILED; @@ -349,7 +349,7 @@ static void CreateSettingUIExtensionMainThread(std::shared_ptrabilityContext, - asyncContext->uiExtensionContext, asyncContext->uiAbilityFlag); + asyncContext->uiExtensionContext, asyncContext->windowId, asyncContext->isWithWindowId, asyncContext->uiAbilityFlag); if (uiContent == nullptr) { LOGE(ATM_DOMAIN, ATM_TAG, "Failed to get ui content!"); asyncContext->result.errorCode = RET_FAILED; @@ -423,7 +423,7 @@ static void GetInstanceId(std::shared_ptr& asy { auto task = [asyncContext]() { Ace::UIContent* uiContent = GetUIContent(asyncContext->abilityContext, - asyncContext->uiExtensionContext, asyncContext->uiAbilityFlag); + asyncContext->uiExtensionContext, asyncContext->windowId, asyncContext->isWithWindowId, asyncContext->uiAbilityFlag); if (uiContent == nullptr) { LOGE(ATM_DOMAIN, ATM_TAG, "Failed to get ui content!"); return; diff --git a/frameworks/ets/ani/common/include/ani_utils.h b/frameworks/ets/ani/common/include/ani_utils.h index f91226910..f74d58438 100644 --- a/frameworks/ets/ani/common/include/ani_utils.h +++ b/frameworks/ets/ani/common/include/ani_utils.h @@ -34,7 +34,7 @@ bool AniClassFindField(ani_env* env, const ani_class& aniClass, const std::strin bool AniParseCallback(ani_env* env, const ani_ref& ani_callback, ani_ref& out); bool AniIsRefUndefined(ani_env* env, const ani_ref& ref); -bool AniParseUint32(ani_env* env, const ani_int& aniInt, uint32_t& out); +bool AniParseUint32(ani_env* env, const ani_ref& aniInt, uint32_t& out); bool AniParseAccessTokenIDArray(ani_env* env, const ani_array_ref& array, std::vector& out); bool GetBoolProperty(ani_env* env, const ani_object& object, const std::string& property, bool& value); -- Gitee From 21dca7cdbe23381cd0f6196e01acd758c51f011a Mon Sep 17 00:00:00 2001 From: GaoShuo Date: Tue, 12 Aug 2025 09:46:44 +0800 Subject: [PATCH 2/2] tmp --- bundle.json | 1 + frameworks/ets/ani/accesstoken/BUILD.gn | 2 + frameworks/js/napi/accesstoken/BUILD.gn | 2 + .../napi/accesstoken/src/napi_atmanager.cpp | 2 + .../src/napi_request_permission.cpp | 231 +++++++++++++++++- .../napi_request_permission_on_setting.cpp | 99 +++++++- .../include/napi_request_permission.h | 6 + .../napi_request_permission_on_setting.h | 5 + 8 files changed, 343 insertions(+), 5 deletions(-) diff --git a/bundle.json b/bundle.json index 24e7d242d..aa5b983bf 100644 --- a/bundle.json +++ b/bundle.json @@ -42,6 +42,7 @@ "dsoftbus", "eventhandler", "ffrt", + "graphic_2d", "hicollie", "hisysevent", "hitrace", diff --git a/frameworks/ets/ani/accesstoken/BUILD.gn b/frameworks/ets/ani/accesstoken/BUILD.gn index cd5ebb400..83ae76b29 100644 --- a/frameworks/ets/ani/accesstoken/BUILD.gn +++ b/frameworks/ets/ani/accesstoken/BUILD.gn @@ -56,6 +56,7 @@ ohos_shared_library("accesstoken_ani") { "ability_runtime:ui_extension", "ace_engine:ace_uicontent", "c_utils:utils", + "graphic_2d:librender_service_base", "hilog:libhilog", "hisysevent:libhisysevent", "init:libbegetutil", @@ -63,6 +64,7 @@ ohos_shared_library("accesstoken_ani") { "napi:ace_napi", "runtime_core:ani", "runtime_core:libarkruntime", + "window_manager:libwm", ] if (eventhandler_enable == true) { diff --git a/frameworks/js/napi/accesstoken/BUILD.gn b/frameworks/js/napi/accesstoken/BUILD.gn index 6cebe5c4c..bd9050a5e 100644 --- a/frameworks/js/napi/accesstoken/BUILD.gn +++ b/frameworks/js/napi/accesstoken/BUILD.gn @@ -55,11 +55,13 @@ ohos_shared_library("libabilityaccessctrl") { "ability_runtime:ui_extension", "ace_engine:ace_uicontent", "c_utils:utils", + "graphic_2d:librender_service_base", "hilog:libhilog", "hisysevent:libhisysevent", "init:libbegetutil", "ipc:ipc_single", "napi:ace_napi", + "window_manager:libwm", ] if (eventhandler_enable == true) { diff --git a/frameworks/js/napi/accesstoken/src/napi_atmanager.cpp b/frameworks/js/napi/accesstoken/src/napi_atmanager.cpp index d0279afb6..0b71be2eb 100644 --- a/frameworks/js/napi/accesstoken/src/napi_atmanager.cpp +++ b/frameworks/js/napi/accesstoken/src/napi_atmanager.cpp @@ -238,8 +238,10 @@ napi_value NapiAtManager::Init(napi_env env, napi_value exports) DECLARE_NAPI_FUNCTION("setPermissionRequestToggleStatus", SetPermissionRequestToggleStatus), DECLARE_NAPI_FUNCTION("getPermissionRequestToggleStatus", GetPermissionRequestToggleStatus), DECLARE_NAPI_FUNCTION("requestPermissionsFromUser", NapiRequestPermission::RequestPermissionsFromUser), + DECLARE_NAPI_FUNCTION("requestPermissionsFromUserWithWindowId", NapiRequestPermission::RequestPermissionsFromUserWithWindowId), DECLARE_NAPI_FUNCTION("getPermissionsStatus", NapiRequestPermission::GetPermissionsStatus), DECLARE_NAPI_FUNCTION("requestPermissionOnSetting", NapiRequestPermissionOnSetting::RequestPermissionOnSetting), + DECLARE_NAPI_FUNCTION("requestPermissionOnSettingWithWindowId", NapiRequestPermissionOnSetting::RequestPermissionOnSettingWithWindowId), DECLARE_NAPI_FUNCTION("requestGlobalSwitch", NapiRequestGlobalSwitch::RequestGlobalSwitch), DECLARE_NAPI_FUNCTION("requestPermissionOnApplicationSetting", RequestAppPermOnSetting), DECLARE_NAPI_FUNCTION("getSelfPermissionStatus", GetSelfPermissionStatusSync), diff --git a/frameworks/js/napi/accesstoken/src/napi_request_permission.cpp b/frameworks/js/napi/accesstoken/src/napi_request_permission.cpp index 3412d6280..f36dc9d5a 100644 --- a/frameworks/js/napi/accesstoken/src/napi_request_permission.cpp +++ b/frameworks/js/napi/accesstoken/src/napi_request_permission.cpp @@ -22,8 +22,10 @@ #include "hisysevent.h" #include "napi_base_context.h" #include "napi_hisysevent_adapter.h" +#include "refbase.h" #include "token_setproc.h" #include "want.h" +#include "window.h" namespace OHOS { namespace Security { @@ -91,7 +93,17 @@ static Ace::UIContent* GetUIContent(std::shared_ptr asyncCo return nullptr; } Ace::UIContent* uiContent = nullptr; - if (asyncContext->uiAbilityFlag) { + if (asyncContext->isWithWindowId) { + sptr window = OHOS::Rosen::Window::GetWindowWithId(asyncContext->windowId); + if(window == nullptr) { + LOGE(ATM_DOMAIN, ATM_TAG, "Get window with id %{public}d failed", asyncContext->windowId); + (void)HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::ACCESS_TOKEN, "REQ_PERM_FROM_USER_ERROR", + HiviewDFX::HiSysEvent::EventType::FAULT, "ERROR_CODE", GET_UI_CONTENT_FAILED); + return nullptr; + } + LOGE(ATM_DOMAIN, ATM_TAG, "Get window with id %{public}d success", asyncContext->windowId); + uiContent = window->GetUIContent(); + } else if (asyncContext->uiAbilityFlag) { uiContent = asyncContext->abilityContext->GetUIContent(); } else { uiContent = asyncContext->uiExtensionContext->GetUIContent(); @@ -205,9 +217,14 @@ static napi_value GetContext( LOGE(ATM_DOMAIN, ATM_TAG, "Get context failed"); return nullptr; } - asyncContext->abilityContext = - AbilityRuntime::Context::ConvertTo(context); - if ((asyncContext->abilityContext != nullptr) && + asyncContext->context = context; + // asyncContext->abilityContext = + // AbilityRuntime::Context::ConvertTo(context); + if (asyncContext->isWithWindowId && context->GetApplicationInfo()) { + asyncContext->tokenId = asyncContext->context->GetApplicationInfo()->accessTokenId; + asyncContext->bundleName = asyncContext->context->GetApplicationInfo()->bundleName; + } + else if ((asyncContext->abilityContext != nullptr) && (asyncContext->abilityContext->GetApplicationInfo() != nullptr)) { asyncContext->uiAbilityFlag = true; asyncContext->tokenId = asyncContext->abilityContext->GetApplicationInfo()->accessTokenId; @@ -417,6 +434,63 @@ static void CreateServiceExtension(std::shared_ptr asyncCon ret, asyncContext->tokenId, asyncContext->permissionList.size()); } +static void CreateServiceExtensionWithWindowId(std::shared_ptr asyncContext) +{ + if ((asyncContext == nullptr) || (asyncContext->context == nullptr)) { + return; + } + // if (!asyncContext->uiAbilityFlag) { + // LOGE(ATM_DOMAIN, ATM_TAG, "UIExtension ability can not pop service ablility window!"); + // asyncContext->needDynamicRequest = false; + // asyncContext->result.errorCode = RET_FAILED; + // (void)HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::ACCESS_TOKEN, "REQ_PERM_FROM_USER_ERROR", + // HiviewDFX::HiSysEvent::EventType::FAULT, "ERROR_CODE", ABILITY_FLAG_ERROR); + // return; + // } + sptr remoteObject = new (std::nothrow) AccessToken::AuthorizationResult(asyncContext); + if (remoteObject == nullptr) { + LOGE(ATM_DOMAIN, ATM_TAG, "Create window failed!"); + asyncContext->needDynamicRequest = false; + asyncContext->result.errorCode = RET_FAILED; + return; + } + AAFwk::Want want; + want.SetElementName(asyncContext->info.grantBundleName, asyncContext->info.grantServiceAbilityName); + want.SetParam(PERMISSION_KEY, asyncContext->permissionList); + want.SetParam(STATE_KEY, asyncContext->permissionsState); + want.SetParam(TOKEN_KEY, asyncContext->context->GetToken()); + want.SetParam(CALLBACK_KEY, remoteObject); + + sptr window = OHOS::Rosen::Window::GetWindowWithId(asyncContext->windowId); + + if (window == nullptr) { + LOGE(ATM_DOMAIN, ATM_TAG, "GetWindowWithId failed, windowId: %{public}d", asyncContext->windowId); + asyncContext->needDynamicRequest = false; + asyncContext->result.errorCode = RET_FAILED; + (void)HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::ACCESS_TOKEN, "REQ_PERM_FROM_USER_ERROR", + HiviewDFX::HiSysEvent::EventType::FAULT, "ERROR_CODE", GET_UI_CONTENT_FAILED); + return; + } + + Rosen::Rect windowRect = window->GetRect(); + + int32_t left = windowRect.posX_; + int32_t top = windowRect.posY_; + int32_t width = windowRect.width_; + int32_t height = windowRect.height_; + + want.SetParam(WINDOW_RECTANGLE_LEFT_KEY, left); + want.SetParam(WINDOW_RECTANGLE_TOP_KEY, top); + want.SetParam(WINDOW_RECTANGLE_WIDTH_KEY, width); + want.SetParam(WINDOW_RECTANGLE_HEIGHT_KEY, height); + want.SetParam(REQUEST_TOKEN_KEY, asyncContext->context->GetToken()); + int32_t ret = AAFwk::AbilityManagerClient::GetInstance()->RequestDialogService( + want, asyncContext->context->GetToken()); + + LOGI(ATM_DOMAIN, ATM_TAG, "Request end, ret: %{public}d, tokenId: %{public}d, permNum: %{public}zu", + ret, asyncContext->tokenId, asyncContext->permissionList.size()); +} + bool NapiRequestPermission::IsDynamicRequest(std::shared_ptr& asyncContext) { std::vector permList; @@ -769,6 +843,152 @@ void NapiRequestPermission::RequestPermissionsFromUserComplete(napi_env env, nap } } +napi_value NapiRequestPermission::RequestPermissionsFromUserWithWindowId(napi_env env, napi_callback_info info) +{ + LOGD(ATM_DOMAIN, ATM_TAG, "RequestPermissionsFromUserWithWindowId begin."); + // use handle to protect asyncContext + std::shared_ptr asyncContext = std::make_shared(env); + asyncContext->isWithWindowId = true; + asyncContext->windowId = 0; + + if (!ParseRequestPermissionFromUserWithWindowId(env, info, asyncContext)) { + return nullptr; + } + auto asyncContextHandle = std::make_unique(asyncContext); + napi_value result = nullptr; + if (asyncContextHandle->asyncContextPtr->callbackRef == nullptr) { + NAPI_CALL(env, napi_create_promise(env, &(asyncContextHandle->asyncContextPtr->deferred), &result)); + } else { + NAPI_CALL(env, napi_get_undefined(env, &result)); + } + + napi_value resource = nullptr; // resource name + NAPI_CALL(env, napi_create_string_utf8(env, "RequestPermissionsFromUserWithWindowId", NAPI_AUTO_LENGTH, &resource)); + NAPI_CALL(env, napi_create_async_work( + env, nullptr, resource, RequestPermissionsFromUserWithWindowIdExecute, RequestPermissionsFromUserComplete, + reinterpret_cast(asyncContextHandle.get()), &(asyncContextHandle->asyncContextPtr->work))); + + NAPI_CALL(env, + napi_queue_async_work_with_qos(env, asyncContextHandle->asyncContextPtr->work, napi_qos_user_initiated)); + + LOGD(ATM_DOMAIN, ATM_TAG, "RequestPermissionsFromUser end."); + asyncContextHandle.release(); + return result; +} + +bool NapiRequestPermission::ParseRequestPermissionFromUserWithWindowId(const napi_env& env, + const napi_callback_info& cbInfo, std::shared_ptr& asyncContext) +{ + size_t argc = NapiContextCommon::MAX_PARAMS_FOUR; + napi_value argv[NapiContextCommon::MAX_PARAMS_FOUR] = { nullptr }; + napi_value thisVar = nullptr; + + if (napi_get_cb_info(env, cbInfo, &argc, argv, &thisVar, nullptr) != napi_ok) { + LOGE(ATM_DOMAIN, ATM_TAG, "Napi_get_cb_info failed"); + return false; + } + if (argc < NapiContextCommon::MAX_PARAMS_FOUR - 1) { + NAPI_CALL_BASE(env, napi_throw(env, GenerateBusinessError(env, + JsErrorCode::JS_ERROR_PARAM_ILLEGAL, "Parameter is missing.")), false); + return false; + } + asyncContext->env = env; + std::string errMsg; + + // argv[0] : context : AbilityContext + if (GetContext(env, argv[0], asyncContext) == nullptr) { + errMsg = GetParamErrorMsg("context", "UIAbility or UIExtension Context"); + NAPI_CALL_BASE( + env, napi_throw(env, GenerateBusinessError(env, JsErrorCode::JS_ERROR_PARAM_ILLEGAL, errMsg)), false); + return false; + } + LOGI(ATM_DOMAIN, ATM_TAG, "AsyncContext.uiAbilityFlag is: %{public}d.", asyncContext->uiAbilityFlag); + + // argv[1] : windowId + if (!ParseUint32(env, argv[1], asyncContext->windowId)) { + errMsg = GetParamErrorMsg("windowId", "WindowId"); + NAPI_CALL_BASE( + env, napi_throw(env, GenerateBusinessError(env, JsErrorCode::JS_ERROR_PARAM_ILLEGAL, errMsg)), false); + return false; + } + + // argv[2] : permissionList + if (!ParseStringArray(env, argv[2], asyncContext->permissionList) || + (asyncContext->permissionList.empty())) { + errMsg = GetParamErrorMsg("permissionList", "Array"); + NAPI_CALL_BASE( + env, napi_throw(env, GenerateBusinessError(env, JsErrorCode::JS_ERROR_PARAM_ILLEGAL, errMsg)), false); + return false; + } + + if (argc == NapiContextCommon::MAX_PARAMS_FOUR) { + // argv[3] : callback + if (!IsUndefinedOrNull(env, argv[3]) && !ParseCallback(env, argv[3], asyncContext->callbackRef)) { + errMsg = GetParamErrorMsg("callback", "Callback"); + napi_throw(env, GenerateBusinessError(env, JsErrorCode::JS_ERROR_PARAM_ILLEGAL, errMsg)); + return false; + } + } +#ifdef EVENTHANDLER_ENABLE + asyncContext->handler_ = std::make_shared(AppExecFwk::EventRunner::GetMainEventRunner()); +#endif + return true; +} + +void NapiRequestPermission::RequestPermissionsFromUserWithWindowIdExecute(napi_env env, void* data) +{ + // asyncContext release in complete. + RequestAsyncContextHandle* asyncContextHandle = reinterpret_cast(data); + if (asyncContextHandle == nullptr || asyncContextHandle->asyncContextPtr == nullptr) { + LOGE(ATM_DOMAIN, ATM_TAG, "AsyncContext is null."); + return; + } + static AccessTokenID selfTokenID = static_cast(GetSelfTokenID()); + if (asyncContextHandle->asyncContextPtr->tokenId != selfTokenID) { + LOGE(ATM_DOMAIN, ATM_TAG, "The context tokenID: %{public}d, selfTokenID: %{public}d.", + asyncContextHandle->asyncContextPtr->tokenId, selfTokenID); + asyncContextHandle->asyncContextPtr->result.errorCode = RET_FAILED; + asyncContextHandle->asyncContextPtr->result.errorMsg = + "The specified context does not belong to the current application."; + (void)HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::ACCESS_TOKEN, "REQ_PERM_FROM_USER_ERROR", + HiviewDFX::HiSysEvent::EventType::FAULT, "ERROR_CODE", TOKENID_INCONSISTENCY, + "SELF_TOKEN", selfTokenID, "CONTEXT_TOKEN", asyncContextHandle->asyncContextPtr->tokenId); + return; + } + + if (!IsDynamicRequest(asyncContextHandle->asyncContextPtr)) { + LOGI(ATM_DOMAIN, ATM_TAG, "It does not need to request permission"); + asyncContextHandle->asyncContextPtr->needDynamicRequest = false; + return; + } + + GetInstanceId(asyncContextHandle->asyncContextPtr); + std::string bundleName = asyncContextHandle->asyncContextPtr->bundleName; + // service extension dialog + if (asyncContextHandle->asyncContextPtr->info.grantBundleName == ORI_PERMISSION_MANAGER_BUNDLE_NAME) { + LOGI(ATM_DOMAIN, ATM_TAG, "Pop service extension dialog, uiContentFlag=%{public}d", + asyncContextHandle->asyncContextPtr->uiContentFlag); + if (asyncContextHandle->asyncContextPtr->uiContentFlag) { + RequestAsyncInstanceControl::AddCallbackByInstanceId(asyncContextHandle->asyncContextPtr); + } else { + CreateServiceExtensionWithWindowId(asyncContextHandle->asyncContextPtr); + } + } else if (asyncContextHandle->asyncContextPtr->instanceId == -1) { + LOGI(ATM_DOMAIN, ATM_TAG, "Pop service extension dialog, instanceId is -1."); + CreateServiceExtensionWithWindowId(asyncContextHandle->asyncContextPtr); + ReportHisysEventReqPermsFromUserBehavior(bundleName, false); + } else { + LOGI(ATM_DOMAIN, ATM_TAG, "Pop ui extension dialog"); + asyncContextHandle->asyncContextPtr->uiExtensionFlag = true; + RequestAsyncInstanceControl::AddCallbackByInstanceId(asyncContextHandle->asyncContextPtr); + ReportHisysEventReqPermsFromUserBehavior(bundleName, asyncContextHandle->asyncContextPtr->uiExtensionFlag); + if (!asyncContextHandle->asyncContextPtr->uiExtensionFlag) { + LOGW(ATM_DOMAIN, ATM_TAG, "Pop uiextension dialog fail, start to pop service extension dialog."); + RequestAsyncInstanceControl::AddCallbackByInstanceId(asyncContextHandle->asyncContextPtr); + } + } +} + napi_value NapiRequestPermission::GetPermissionsStatus(napi_env env, napi_callback_info info) { LOGD(ATM_DOMAIN, ATM_TAG, "GetPermissionsStatus begin."); @@ -923,6 +1143,9 @@ void RequestAsyncInstanceControl::AddCallbackByInstanceId(std::shared_ptruiExtensionFlag) { CreateUIExtension(asyncContext); + } else if(asyncContext->isWithWindowId) { + //CreateServiceExtensionWithWindowId(asyncContext); + CreateUIExtension(asyncContext); } else { CreateServiceExtension(asyncContext); } diff --git a/frameworks/js/napi/accesstoken/src/napi_request_permission_on_setting.cpp b/frameworks/js/napi/accesstoken/src/napi_request_permission_on_setting.cpp index e14d167db..b2f491ba5 100644 --- a/frameworks/js/napi/accesstoken/src/napi_request_permission_on_setting.cpp +++ b/frameworks/js/napi/accesstoken/src/napi_request_permission_on_setting.cpp @@ -20,6 +20,7 @@ #include "napi_base_context.h" #include "token_setproc.h" #include "want.h" +#include "window.h" namespace OHOS { namespace Security { @@ -97,7 +98,15 @@ static Ace::UIContent* GetUIContent(std::shared_ptruiAbilityFlag) { + if (asyncContext->isWithWindowId) { + sptr window = OHOS::Rosen::Window::GetWindowWithId(asyncContext->windowId); + if(window == nullptr) { + LOGE(ATM_DOMAIN, ATM_TAG, "Get window with id %{public}d failed", asyncContext->windowId); + return nullptr; + } + uiContent = window->GetUIContent(); + + } else if (asyncContext->uiAbilityFlag) { uiContent = asyncContext->abilityContext->GetUIContent(); } else { uiContent = asyncContext->uiExtensionContext->GetUIContent(); @@ -682,6 +691,94 @@ void NapiRequestPermissionOnSetting::RequestPermissionOnSettingComplete(napi_env napi_reject_deferred(env, asyncContextHandle->asyncContextPtr->deferred, businessError)); } } + +napi_value NapiRequestPermissionOnSetting::RequestPermissionOnSettingWithWindowId(napi_env env, napi_callback_info info) +{ + LOGD(ATM_DOMAIN, ATM_TAG, "RequestPermissionOnSettingWithWindowId begin."); + // use handle to protect asyncContext + std::shared_ptr asyncContext = + std::make_shared(env); + asyncContext->isWithWindowId = true; + asyncContext->windowId = 0; + + if (!ParseRequestPermissionOnSettingWithWindowId(env, info, asyncContext)) { + return nullptr; + } + auto asyncContextHandle = std::make_unique(asyncContext); + if (asyncContextHandle->asyncContextPtr == nullptr) { + LOGE(ATM_DOMAIN, ATM_TAG, "Async context is null."); + return nullptr; + } + napi_value result = nullptr; + if (asyncContextHandle->asyncContextPtr->callbackRef == nullptr) { + NAPI_CALL(env, napi_create_promise(env, &(asyncContextHandle->asyncContextPtr->deferred), &result)); + } else { + NAPI_CALL(env, napi_get_undefined(env, &result)); + } + + napi_value resource = nullptr; // resource name + NAPI_CALL(env, napi_create_string_utf8(env, "RequestPermissionOnSettingWithWindowId", NAPI_AUTO_LENGTH, &resource)); + NAPI_CALL(env, napi_create_async_work( + env, nullptr, resource, RequestPermissionOnSettingExecute, RequestPermissionOnSettingComplete, + reinterpret_cast(asyncContextHandle.get()), &(asyncContextHandle->asyncContextPtr->work))); + + NAPI_CALL(env, + napi_queue_async_work_with_qos(env, asyncContextHandle->asyncContextPtr->work, napi_qos_user_initiated)); + + LOGD(ATM_DOMAIN, ATM_TAG, "RequestPermissionOnSetting end."); + asyncContextHandle.release(); + return result; +} + +bool NapiRequestPermissionOnSetting::ParseRequestPermissionOnSettingWithWindowId(const napi_env& env, + const napi_callback_info& cbInfo, std::shared_ptr& asyncContext) +{ + size_t argc = NapiContextCommon::MAX_PARAMS_THREE; + napi_value argv[NapiContextCommon::MAX_PARAMS_THREE] = { nullptr }; + napi_value thisVar = nullptr; + + if (napi_get_cb_info(env, cbInfo, &argc, argv, &thisVar, nullptr) != napi_ok) { + LOGE(ATM_DOMAIN, ATM_TAG, "Napi_get_cb_info failed"); + return false; + } + if (argc < NapiContextCommon::MAX_PARAMS_THREE - 1) { + NAPI_CALL_BASE(env, napi_throw(env, GenerateBusinessError(env, + JsErrorCode::JS_ERROR_PARAM_ILLEGAL, "Parameter is missing.")), false); + return false; + } + asyncContext->env = env; + std::string errMsg; + + // argv[0] : context : AbilityContext + if (GetContext(env, argv[0], asyncContext) == nullptr) { + errMsg = GetParamErrorMsg("context", "UIAbility or UIExtension Context"); + NAPI_CALL_BASE( + env, napi_throw(env, GenerateBusinessError(env, JsErrorCode::JS_ERROR_PARAM_ILLEGAL, errMsg)), false); + return false; + } + LOGI(ATM_DOMAIN, ATM_TAG, "AsyncContext.uiAbilityFlag is: %{public}d.", asyncContext->uiAbilityFlag); + + // argv[1] : windowId : uint32 + if (!ParseUint32(env, argv[1], asyncContext->windowId)) { + errMsg = GetParamErrorMsg("windowId", "WindowId"); + NAPI_CALL_BASE( + env, napi_throw(env, GenerateBusinessError(env, JsErrorCode::JS_ERROR_PARAM_ILLEGAL, errMsg)), false); + return false; + } + + // argv[2] : permissionList + if (!ParseStringArray(env, argv[2], asyncContext->permissionList) || + (asyncContext->permissionList.empty())) { + errMsg = GetParamErrorMsg("permissionList", "Array"); + NAPI_CALL_BASE( + env, napi_throw(env, GenerateBusinessError(env, JsErrorCode::JS_ERROR_PARAM_ILLEGAL, errMsg)), false); + return false; + } +#ifdef EVENTHANDLER_ENABLE + asyncContext->handler_ = std::make_shared(AppExecFwk::EventRunner::GetMainEventRunner()); +#endif + return true; +} } // namespace AccessToken } // namespace Security } // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/napi/accesstoken/include/napi_request_permission.h b/interfaces/kits/js/napi/accesstoken/include/napi_request_permission.h index 45cd3f390..875afe52f 100644 --- a/interfaces/kits/js/napi/accesstoken/include/napi_request_permission.h +++ b/interfaces/kits/js/napi/accesstoken/include/napi_request_permission.h @@ -40,6 +40,7 @@ struct RequestAsyncContext : public AtManagerAsyncWorkData { bool needDynamicRequest = true; AtmResult result; int32_t instanceId = -1; + uint32_t windowId = 0; std::vector permissionList; std::vector permissionsState; napi_value requestResult = nullptr; @@ -49,6 +50,7 @@ struct RequestAsyncContext : public AtManagerAsyncWorkData { PermissionGrantInfo info; std::shared_ptr abilityContext; std::shared_ptr uiExtensionContext; + bool isWithWindowId = false; bool uiAbilityFlag = false; bool uiExtensionFlag = false; bool uiContentFlag = false; @@ -121,6 +123,7 @@ class NapiRequestPermission { public: static bool IsDynamicRequest(std::shared_ptr& asyncContext); static napi_value RequestPermissionsFromUser(napi_env env, napi_callback_info info); + static napi_value RequestPermissionsFromUserWithWindowId(napi_env env, napi_callback_info info); static napi_value GetPermissionsStatus(napi_env env, napi_callback_info info); private: @@ -128,6 +131,9 @@ private: std::shared_ptr& asyncContext); static void RequestPermissionsFromUserExecute(napi_env env, void* data); static void RequestPermissionsFromUserComplete(napi_env env, napi_status status, void* data); + static bool ParseRequestPermissionFromUserWithWindowId( + const napi_env& env, const napi_callback_info& cbInfo, std::shared_ptr& asyncContext); + static void RequestPermissionsFromUserWithWindowIdExecute(napi_env env, void* data); static bool ParseInputToGetQueryResult(const napi_env& env, const napi_callback_info& info, RequestAsyncContext& asyncContext); static void GetPermissionsStatusExecute(napi_env env, void *data); diff --git a/interfaces/kits/js/napi/accesstoken/include/napi_request_permission_on_setting.h b/interfaces/kits/js/napi/accesstoken/include/napi_request_permission_on_setting.h index 8c0e8dbb1..376424d06 100644 --- a/interfaces/kits/js/napi/accesstoken/include/napi_request_permission_on_setting.h +++ b/interfaces/kits/js/napi/accesstoken/include/napi_request_permission_on_setting.h @@ -44,6 +44,8 @@ struct RequestPermOnSettingAsyncContext : public AtManagerAsyncWorkData { napi_value requestResult = nullptr; int32_t errorCode = -1; std::vector stateList; + uint32_t windowId = 0; + bool isWithWindowId = false; std::shared_ptr abilityContext; std::shared_ptr uiExtensionContext; @@ -102,10 +104,13 @@ struct PermissonOnSettingResultCallback { class NapiRequestPermissionOnSetting { public: static napi_value RequestPermissionOnSetting(napi_env env, napi_callback_info info); + static napi_value RequestPermissionOnSettingWithWindowId(napi_env env, napi_callback_info info); private: static bool ParseRequestPermissionOnSetting(const napi_env& env, const napi_callback_info& cbInfo, std::shared_ptr& asyncContext); + static bool ParseRequestPermissionOnSettingWithWindowId(const napi_env& env, const napi_callback_info& cbInfo, + std::shared_ptr& asyncContext); static void RequestPermissionOnSettingExecute(napi_env env, void* data); static void RequestPermissionOnSettingComplete(napi_env env, napi_status status, void* data); }; -- Gitee