From 24a2c84f860b73acb0b55fe405a6959f22db791e Mon Sep 17 00:00:00 2001 From: zhouyan Date: Tue, 16 Aug 2022 10:58:55 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A8=A1=E7=B3=8A=E6=9D=83=E9=99=90=E4=B8=8E?= =?UTF-8?q?=E7=B2=BE=E5=87=86=E6=9D=83=E9=99=90native=E5=8A=9F=E8=83=BD?= =?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: Ia5925aea851e6e2996abfe0bd5d565509f73b342 --- .../include/permission/permission_manager.h | 14 ++ .../cpp/src/permission/permission_manager.cpp | 154 +++++++++++++++++- .../service/accesstoken_manager_service.cpp | 14 ++ 3 files changed, 180 insertions(+), 2 deletions(-) diff --git a/services/accesstokenmanager/main/cpp/include/permission/permission_manager.h b/services/accesstokenmanager/main/cpp/include/permission/permission_manager.h index 30f6d542a..bc313e52b 100644 --- a/services/accesstokenmanager/main/cpp/include/permission/permission_manager.h +++ b/services/accesstokenmanager/main/cpp/include/permission/permission_manager.h @@ -24,6 +24,7 @@ #include "iremote_broker.h" #include "permission_def.h" #include "permission_list_state.h" +#include "permission_list_state_parcel.h" #include "permission_state_change_info.h" #include "permission_state_full.h" @@ -33,6 +34,10 @@ namespace OHOS { namespace Security { namespace AccessToken { +static const std::string VAGUE_LOCATION_PERMISSION_NAME = "ohos.permission.APPROXIMATELY_LOCATION"; +static const std::string ACCURATE_LOCATION_PERMISSION_NAME = "ohos.permission.LOCATION"; +static int ELEMENT_NOT_FOUND = -1; + class PermissionManager final { public: static PermissionManager& GetInstance(); @@ -58,12 +63,21 @@ public: int32_t AddPermStateChangeCallback( const PermStateChangeScope& scope, const sptr& callback); int32_t RemovePermStateChangeCallback(const sptr& callback); + void GetLocationPermissionIndex(std::vector& reqPermList, int& vagueIndex, + int& accurateIndex); + void LocationPermissionSpecialHandle(std::vector& reqPermList, + std::vector permsList, int vagueIndex, int accurateIndex, bool& needRes); private: PermissionManager(); void UpdateTokenPermissionState( AccessTokenID tokenID, const std::string& permissionName, bool isGranted, int flag); std::string TransferPermissionDefToString(const PermissionDef& inPermissionDef); + bool IsPermissionVaild(const std::string& permissionName); + bool GetPermissionStatusAndFlag(const std::string& permissionName, std::vector permsList, + int32_t& status, uint32_t& flag); + void AllLocationPermissionHandle(std::vector& reqPermList, + std::vector permsList, int vagueIndex, int accurateIndex); DISALLOW_COPY_AND_MOVE(PermissionManager); }; diff --git a/services/accesstokenmanager/main/cpp/src/permission/permission_manager.cpp b/services/accesstokenmanager/main/cpp/src/permission/permission_manager.cpp index 4819bf776..fdeb7fa71 100644 --- a/services/accesstokenmanager/main/cpp/src/permission/permission_manager.cpp +++ b/services/accesstokenmanager/main/cpp/src/permission/permission_manager.cpp @@ -246,8 +246,8 @@ void PermissionManager::GetSelfPermissionState(std::vector uint32_t goalGrantFlags; for (const auto& perm : permsList) { if (perm.permissionName == permState.permissionName) { - ACCESSTOKEN_LOG_INFO(LABEL, - "find goal permission: %{public}s!", permState.permissionName.c_str()); + ACCESSTOKEN_LOG_INFO(LABEL, "find goal permission: %{public}s, status: %{public}d, flag: %{public}d", + permState.permissionName.c_str(), perm.grantStatus[0], perm.grantFlags[0]); foundGoal = true; goalGrantStatus = perm.grantStatus[0]; goalGrantFlags = static_cast(perm.grantFlags[0]); @@ -405,6 +405,156 @@ int32_t PermissionManager::RemovePermStateChangeCallback(const sptr& reqPermList, + int& vagueIndex, int& accurateIndex) +{ + int index = 0; + + for (const auto& perm : reqPermList) { + if (perm.permsState.permissionName == VAGUE_LOCATION_PERMISSION_NAME) { + vagueIndex = index; + } + + if (perm.permsState.permissionName == ACCURATE_LOCATION_PERMISSION_NAME) { + accurateIndex = index; + } + + index++; + + if ((vagueIndex != ELEMENT_NOT_FOUND) && (accurateIndex != ELEMENT_NOT_FOUND)) { + break; + } + } + + ACCESSTOKEN_LOG_INFO(LABEL, "vague location permission index is %{public}d!", vagueIndex); + ACCESSTOKEN_LOG_INFO(LABEL, "accurate location permission index is %{public}d!", accurateIndex); +} + +bool PermissionManager::IsPermissionVaild(const std::string& permissionName) +{ + if (!PermissionValidator::IsPermissionNameValid(permissionName)) { + ACCESSTOKEN_LOG_WARN(LABEL, "invalid permissionName %{public}s", permissionName.c_str()); + + return false; + } + + if (!PermissionDefinitionCache::GetInstance().HasDefinition(permissionName)) { + ACCESSTOKEN_LOG_WARN(LABEL, "permission %{public}s has no definition ", permissionName.c_str()); + + return false; + } + + return true; +} + +bool PermissionManager::GetPermissionStatusAndFlag(const std::string& permissionName, + std::vector permsList, int32_t& status, uint32_t& flag) +{ + if (!IsPermissionVaild(permissionName)) { + ACCESSTOKEN_LOG_WARN(LABEL, "invalid permission %{public}s", permissionName.c_str()); + + return false; + } + + for (const auto& perm : permsList) { + if (perm.permissionName == permissionName) { + status = perm.grantStatus[0]; + flag = static_cast(perm.grantFlags[0]); + + ACCESSTOKEN_LOG_DEBUG(LABEL, "permission:%{public}s, status:%{public}d, flag:%{public}d!", + permissionName.c_str(), status, flag); + + return true; + } + } + + return false; +} + +void PermissionManager::AllLocationPermissionHandle(std::vector& reqPermList, + std::vector permsList, int vagueIndex, int accurateIndex) +{ + int32_t vagueStatus = PERMISSION_DENIED; + uint32_t vagueFlag = PERMISSION_DEFAULT_FLAG; + int vagueState = INVALID_OPER; + int32_t accurateStatus = PERMISSION_DENIED; + uint32_t accurateFlag = PERMISSION_DEFAULT_FLAG; + int accurateState = INVALID_OPER; + + if (!GetPermissionStatusAndFlag(VAGUE_LOCATION_PERMISSION_NAME, permsList, vagueStatus, vagueFlag) || + !GetPermissionStatusAndFlag(ACCURATE_LOCATION_PERMISSION_NAME, permsList, accurateStatus, accurateFlag)) { + return; + } + // vague location status -1 means vague location permission has been refused + if (vagueStatus == PERMISSION_DENIED) { + if ((vagueFlag == PERMISSION_DEFAULT_FLAG) || ((vagueFlag & PERMISSION_USER_SET) != 0)) { + // vague location flag 0 or 1 means permission has not been operated or valid only once + vagueState = DYNAMIC_OPER; + accurateState = DYNAMIC_OPER; + } else if ((vagueFlag & PERMISSION_USER_FIXED) != 0) { + // vague location flag 2 means vague location has been operated, only can be changed by settings + // so that accurate location is no need to operate + vagueState = SETTING_OPER; + accurateState = SETTING_OPER; + } + } else if (vagueStatus == PERMISSION_GRANTED) { + // vague location status 0 means vague location permission has been accepted + // now flag 1 is not in use so return PASS_OPER, otherwise should judge by flag + vagueState = PASS_OPER; + + if (accurateStatus == PERMISSION_DENIED) { + if ((accurateFlag == PERMISSION_DEFAULT_FLAG) || ((accurateFlag & PERMISSION_USER_SET) != 0)) { + accurateState = DYNAMIC_OPER; + } else if ((accurateFlag & PERMISSION_USER_FIXED) != 0) { + accurateState = SETTING_OPER; + } + } else if (accurateStatus == PERMISSION_GRANTED) { + accurateState = PASS_OPER; + } + } + + ACCESSTOKEN_LOG_INFO(LABEL, "perm: %{public}s, state: %{public}d", VAGUE_LOCATION_PERMISSION_NAME.c_str(), + vagueState); + ACCESSTOKEN_LOG_INFO(LABEL, "perm: %{public}s, state: %{public}d", ACCURATE_LOCATION_PERMISSION_NAME.c_str(), + accurateState); + + reqPermList[vagueIndex].permsState.state = vagueState; + reqPermList[accurateIndex].permsState.state = accurateState; +} + +void PermissionManager::LocationPermissionSpecialHandle(std::vector& reqPermList, + std::vector permsList, int vagueIndex, int accurateIndex, bool& needRes) +{ + if ((vagueIndex != ELEMENT_NOT_FOUND) && (accurateIndex == ELEMENT_NOT_FOUND)) { + // only vague location permission + GetSelfPermissionState(permsList, reqPermList[vagueIndex].permsState); + } else if ((vagueIndex == ELEMENT_NOT_FOUND) && (accurateIndex != ELEMENT_NOT_FOUND)) { + // only accurate location permission refuse directly + reqPermList[accurateIndex].permsState.state = SETTING_OPER; + } else if ((vagueIndex != ELEMENT_NOT_FOUND) && (accurateIndex != ELEMENT_NOT_FOUND)) { + // all location permissions + AllLocationPermissionHandle(reqPermList, permsList, vagueIndex, accurateIndex); + } + + if (vagueIndex != ELEMENT_NOT_FOUND) { + ACCESSTOKEN_LOG_INFO(LABEL, "perm: %{public}s, state: %{public}d", + reqPermList[vagueIndex].permsState.permissionName.c_str(), reqPermList[vagueIndex].permsState.state); + + if (reqPermList[vagueIndex].permsState.state == DYNAMIC_OPER) { + needRes = true; + } + } + + if (accurateIndex != ELEMENT_NOT_FOUND) { + ACCESSTOKEN_LOG_INFO(LABEL, "perm: %{public}s, state: %{public}d", + reqPermList[accurateIndex].permsState.permissionName.c_str(), reqPermList[accurateIndex].permsState.state); + + if (reqPermList[accurateIndex].permsState.state == DYNAMIC_OPER) { + needRes = true; + } + } +} + void PermissionManager::ClearUserGrantedPermissionState(AccessTokenID tokenID) { ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, tokenID: %{public}u", __func__, tokenID); diff --git a/services/accesstokenmanager/main/cpp/src/service/accesstoken_manager_service.cpp b/services/accesstokenmanager/main/cpp/src/service/accesstoken_manager_service.cpp index f09dcdccb..bc2d7b272 100644 --- a/services/accesstokenmanager/main/cpp/src/service/accesstoken_manager_service.cpp +++ b/services/accesstokenmanager/main/cpp/src/service/accesstoken_manager_service.cpp @@ -158,8 +158,22 @@ PermissionOper AccessTokenManagerService::GetSelfPermissionsState( return INVALID_OPER; } + int vagueIndex = ELEMENT_NOT_FOUND; + int accurateIndex = ELEMENT_NOT_FOUND; + + PermissionManager::GetInstance().GetLocationPermissionIndex(reqPermList, vagueIndex, accurateIndex); + if ((vagueIndex != ELEMENT_NOT_FOUND) || (accurateIndex != ELEMENT_NOT_FOUND)) { + PermissionManager::GetInstance().LocationPermissionSpecialHandle(reqPermList, permsList, vagueIndex, + accurateIndex, needRes); // location permission handle here + } + uint32_t size = reqPermList.size(); for (uint32_t i = 0; i < size; i++) { + if ((reqPermList[i].permsState.permissionName == VAGUE_LOCATION_PERMISSION_NAME) || + (reqPermList[i].permsState.permissionName == ACCURATE_LOCATION_PERMISSION_NAME)) { + continue; // location permission special handle above + } + PermissionManager::GetInstance().GetSelfPermissionState( permsList, reqPermList[i].permsState); if (reqPermList[i].permsState.state == DYNAMIC_OPER) { -- Gitee