From 8255ad985b00e4290b2faa70515819b4b62f0434 Mon Sep 17 00:00:00 2001 From: zhouyan Date: Thu, 21 Aug 2025 14:58:42 +0800 Subject: [PATCH] =?UTF-8?q?ark1.2=E6=B7=BB=E5=8A=A0getSelfPermissionStatus?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zhouyan Change-Id: I61fedd5b7699c28eb6f7b8d9364e70e2d6f60205 --- .../ets/@ohos.abilityAccessCtrl.ets | 7 ++ .../include/ani_ability_access_ctrl.h | 13 ++- .../src/ani_ability_access_ctrl.cpp | 110 +++++++++++++++--- 3 files changed, 110 insertions(+), 20 deletions(-) diff --git a/frameworks/ets/ani/accesstoken/ets/@ohos.abilityAccessCtrl.ets b/frameworks/ets/ani/accesstoken/ets/@ohos.abilityAccessCtrl.ets index 8de915f7f..a70c174b0 100644 --- a/frameworks/ets/ani/accesstoken/ets/@ohos.abilityAccessCtrl.ets +++ b/frameworks/ets/ani/accesstoken/ets/@ohos.abilityAccessCtrl.ets @@ -166,6 +166,7 @@ export default namespace abilityAccessCtrl { callback?: Callback): void; off(type: 'permissionStateChange', tokenIDList: Array, permissionList: Array, callback: Callback): void; + getSelfPermissionStatus(permissionName: Permissions): PermissionStatus; } class AtManagerInner implements AtManager { @@ -190,6 +191,7 @@ export default namespace abilityAccessCtrl { native offExcute(type: string, tokenIDList: Array, permissionList: Array, callback?: Callback): void; native requestAppPermOnSettingExecute(tokenID: int): void; + native getSelfPermissionStatusExecute(permissionName: Permissions): int; verifyAccessTokenSync(tokenID: int, permissionName: Permissions): GrantStatus { let result = this.checkAccessTokenExecute(tokenID, permissionName); @@ -471,5 +473,10 @@ export default namespace abilityAccessCtrl { callback?: Callback): void { new AtManagerInner().offExcute('permissionStateChange', tokenIDList, permissionList, callback); } + + getSelfPermissionStatus(permissionName: Permissions): PermissionStatus { + let status = this.getSelfPermissionStatusExecute(permissionName); + return status as PermissionStatus; + } } } diff --git a/frameworks/ets/ani/accesstoken/include/ani_ability_access_ctrl.h b/frameworks/ets/ani/accesstoken/include/ani_ability_access_ctrl.h index 179bd111a..efb54dbf9 100644 --- a/frameworks/ets/ani/accesstoken/include/ani_ability_access_ctrl.h +++ b/frameworks/ets/ani/accesstoken/include/ani_ability_access_ctrl.h @@ -40,10 +40,21 @@ struct PermissionParamCache { std::string sysParamCache; }; -struct PermissionStatusCache { +struct GrantStatusCache { int32_t status; std::string paramValue; }; + +struct AtManagerSyncContext { + std::string permissionName; + PermissionOper permissionsStatus = PermissionOper::INVALID_OPER; + int32_t result = RET_FAILED; +}; + +struct PermStatusCache { + PermissionOper status; + std::string paramValue; +}; } // namespace AccessToken } // namespace Security } // namespace OHOS 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 3bb43e639..92f6ae308 100644 --- a/frameworks/ets/ani/accesstoken/src/ani_ability_access_ctrl.cpp +++ b/frameworks/ets/ani/accesstoken/src/ani_ability_access_ctrl.cpp @@ -39,10 +39,16 @@ namespace { constexpr int32_t VALUE_MAX_LEN = 32; std::mutex g_lockCache; static PermissionParamCache g_paramCache; -std::map g_cache; +std::map g_cache; +static constexpr const char* PERMISSION_STATUS_CHANGE_KEY = "accesstoken.permission.change"; + +std::mutex g_lockStatusCache; +static PermissionParamCache g_paramFlagCache; +std::map g_statusCache; +static constexpr const char* PERMISSION_STATUS_FLAG_CHANGE_KEY = "accesstoken.permission.flagchange"; + static std::atomic g_cnt = 0; constexpr uint32_t REPORT_CNT = 10; -static constexpr const char* PERMISSION_STATUS_CHANGE_KEY = "accesstoken.permission.change"; } constexpr const char* PERM_STATE_CHANGE_FIELD_TOKEN_ID = "tokenID"; constexpr const char* PERM_STATE_CHANGE_FIELD_PERMISSION_NAME = "permissionName"; @@ -204,44 +210,48 @@ static ani_object CreateAtManager([[maybe_unused]] ani_env* env) return atManagerObj; } -static std::string GetPermParamValue() +static std::string GetPermParamValue(PermissionParamCache& paramCache, const char* paramKey) { long long sysCommitId = GetSystemCommitId(); - if (sysCommitId == g_paramCache.sysCommitIdCache) { + if (sysCommitId == paramCache.sysCommitIdCache) { LOGD(ATM_DOMAIN, ATM_TAG, "SysCommitId = %{public}lld.", sysCommitId); - return g_paramCache.sysParamCache; + return paramCache.sysParamCache; } - g_paramCache.sysCommitIdCache = sysCommitId; - if (g_paramCache.handle == PARAM_DEFAULT_VALUE) { - int32_t handle = static_cast(FindParameter(PERMISSION_STATUS_CHANGE_KEY)); + paramCache.sysCommitIdCache = sysCommitId; + if (paramCache.handle == PARAM_DEFAULT_VALUE) { + int32_t handle = static_cast(FindParameter(paramKey)); if (handle == PARAM_DEFAULT_VALUE) { LOGE(ATM_DOMAIN, ATM_TAG, "Failed to FindParameter."); return "-1"; } - g_paramCache.handle = handle; + paramCache.handle = handle; } - int32_t currCommitId = static_cast(GetParameterCommitId(g_paramCache.handle)); - if (currCommitId != g_paramCache.commitIdCache) { + int32_t currCommitId = static_cast(GetParameterCommitId(paramCache.handle)); + if (currCommitId != paramCache.commitIdCache) { char value[VALUE_MAX_LEN] = { 0 }; - auto ret = GetParameterValue(g_paramCache.handle, value, VALUE_MAX_LEN - 1); + auto ret = GetParameterValue(paramCache.handle, value, VALUE_MAX_LEN - 1); if (ret < 0) { LOGE(ATM_DOMAIN, ATM_TAG, "Return default value, ret=%{public}d.", ret); return "-1"; } std::string resStr(value); - g_paramCache.sysParamCache = resStr; - g_paramCache.commitIdCache = currCommitId; + paramCache.sysParamCache = resStr; + paramCache.commitIdCache = currCommitId; } - return g_paramCache.sysParamCache; + return paramCache.sysParamCache; } -static void UpdatePermissionCache(AtManagerAsyncContext* asyncContext) +static void UpdateGrantStatusCache(AtManagerAsyncContext* asyncContext) { + if (asyncContext == nullptr) { + return; + } + std::lock_guard lock(g_lockCache); auto iter = g_cache.find(asyncContext->permissionName); if (iter != g_cache.end()) { - std::string currPara = GetPermParamValue(); + std::string currPara = GetPermParamValue(g_paramCache, PERMISSION_STATUS_CHANGE_KEY); if (currPara != iter->second.paramValue) { asyncContext->grantStatus = AccessToken::AccessTokenKit::VerifyAccessToken(asyncContext->tokenId, asyncContext->permissionName); @@ -255,7 +265,8 @@ static void UpdatePermissionCache(AtManagerAsyncContext* asyncContext) asyncContext->grantStatus = AccessToken::AccessTokenKit::VerifyAccessToken(asyncContext->tokenId, asyncContext->permissionName); g_cache[asyncContext->permissionName].status = asyncContext->grantStatus; - g_cache[asyncContext->permissionName].paramValue = GetPermParamValue(); + g_cache[asyncContext->permissionName].paramValue = GetPermParamValue(g_paramCache, + PERMISSION_STATUS_CHANGE_KEY); LOGD(ATM_DOMAIN, ATM_TAG, "Success to set G_cacheParam(%{public}s).", g_cache[asyncContext->permissionName].paramValue.c_str()); } @@ -297,7 +308,7 @@ static ani_int CheckAccessTokenExecute([[maybe_unused]] ani_env* env, [[maybe_un asyncContext->grantStatus = AccessToken::AccessTokenKit::VerifyAccessToken(tokenID, permissionName); return static_cast(asyncContext->grantStatus); } - UpdatePermissionCache(asyncContext); + UpdateGrantStatusCache(asyncContext); LOGI(ATM_DOMAIN, ATM_TAG, "CheckAccessTokenExecute result : %{public}d.", asyncContext->grantStatus); return static_cast(asyncContext->grantStatus); } @@ -821,6 +832,65 @@ static void UnregisterPermStateChangeCallback([[maybe_unused]] ani_env* env, [[m return; } +static void UpdatePermStatusCache(AtManagerSyncContext* syncContext) +{ + std::lock_guard lock(g_lockStatusCache); + auto iter = g_statusCache.find(syncContext->permissionName); + if (iter != g_statusCache.end()) { + std::string currPara = GetPermParamValue(g_paramFlagCache, PERMISSION_STATUS_FLAG_CHANGE_KEY); + if (currPara != iter->second.paramValue) { + syncContext->result = AccessTokenKit::GetSelfPermissionStatus(syncContext->permissionName, + syncContext->permissionsStatus); + iter->second.status = syncContext->permissionsStatus; + iter->second.paramValue = currPara; + } else { + syncContext->result = RET_SUCCESS; + syncContext->permissionsStatus = iter->second.status; + } + } else { + syncContext->result = AccessTokenKit::GetSelfPermissionStatus(syncContext->permissionName, + syncContext->permissionsStatus); + g_statusCache[syncContext->permissionName].status = syncContext->permissionsStatus; + g_statusCache[syncContext->permissionName].paramValue = GetPermParamValue( + g_paramFlagCache, PERMISSION_STATUS_FLAG_CHANGE_KEY); + } +} + +static ani_int GetSelfPermissionStatusExecute([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object object, + ani_string aniPermissionName) +{ + if (env == nullptr) { + LOGE(ATM_DOMAIN, ATM_TAG, "Env is null."); + return static_cast(PermissionOper::INVALID_OPER); + } + + std::string permissionName = ParseAniString(env, aniPermissionName); + if (!BusinessErrorAni::ValidatePermissionWithThrowError(env, permissionName)) { + return static_cast(PermissionOper::INVALID_OPER); + } + + auto* syncContext = new (std::nothrow) AtManagerSyncContext(); + if (syncContext == nullptr) { + LOGE(ATM_DOMAIN, ATM_TAG, "Failed to alloc memory for syncContext."); + return static_cast(PermissionOper::INVALID_OPER); + } + + std::unique_ptr context { syncContext }; + syncContext->permissionName = permissionName; + + UpdatePermStatusCache(syncContext); + + if (syncContext->result != RET_SUCCESS) { + int32_t stsCode = BusinessErrorAni::GetStsErrorCode(syncContext->result); + BusinessErrorAni::ThrowError(env, stsCode, GetErrorMessage(stsCode)); + return static_cast(PermissionOper::INVALID_OPER); + } + + LOGI(ATM_DOMAIN, ATM_TAG, "PermissionName %{public}s self status is %{public}d.", permissionName.c_str(), + static_cast(syncContext->permissionsStatus)); + return static_cast(syncContext->permissionsStatus); +} + void InitAbilityCtrlFunction(ani_env *env) { if (env == nullptr) { @@ -871,6 +941,8 @@ void InitAbilityCtrlFunction(ani_env *env) nullptr, reinterpret_cast(RequestAppPermOnSettingExecute) }, ani_native_function { "onExcute", nullptr, reinterpret_cast(RegisterPermStateChangeCallback) }, ani_native_function { "offExcute", nullptr, reinterpret_cast(UnregisterPermStateChangeCallback) }, + ani_native_function { "getSelfPermissionStatusExecute", + nullptr, reinterpret_cast(GetSelfPermissionStatusExecute) }, }; if (ANI_OK != env->Class_BindNativeMethods(cls, claMethods.data(), claMethods.size())) { LOGE(ATM_DOMAIN, ATM_TAG, "Cannot bind native methods to %{public}s", className); -- Gitee