From 274c5aea8d60014b71547add20ca7282663eba57 Mon Sep 17 00:00:00 2001 From: zhouyan Date: Tue, 16 Aug 2022 09:37:09 +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: I5a2cc84c9b4a3f8d55133abda2edf5cf4297aca1 --- .../include/i_accesstoken_manager.h | 4 +- .../src/accesstoken_manager_client.cpp | 17 +- .../src/accesstoken_manager_proxy.cpp | 19 ++- .../src/accesstoken_manager_proxy.h | 4 +- .../include/permission/permission_manager.h | 13 ++ .../service/accesstoken_manager_service.h | 2 +- .../cpp/src/permission/permission_manager.cpp | 153 +++++++++++++++++- .../service/accesstoken_manager_service.cpp | 21 ++- .../src/service/accesstoken_manager_stub.cpp | 10 +- 9 files changed, 209 insertions(+), 34 deletions(-) diff --git a/frameworks/accesstoken/include/i_accesstoken_manager.h b/frameworks/accesstoken/include/i_accesstoken_manager.h index 466cafd37..3e1fcf94e 100644 --- a/frameworks/accesstoken/include/i_accesstoken_manager.h +++ b/frameworks/accesstoken/include/i_accesstoken_manager.h @@ -29,7 +29,7 @@ #include "native_token_info_for_sync_parcel.h" #include "native_token_info_parcel.h" #include "permission_def_parcel.h" -#include "permission_list_state_parcel.h" +#include "permission_list_state.h" #include "permission_state_full_parcel.h" #include "permission_state_change_scope_parcel.h" @@ -50,7 +50,7 @@ public: AccessTokenID tokenID, std::vector& reqPermList, bool isSystemGrant) = 0; virtual int GetPermissionFlag(AccessTokenID tokenID, const std::string& permissionName) = 0; virtual PermissionOper GetSelfPermissionsState( - std::vector& permListParcel) = 0; + std::vector& permListParcel) = 0; virtual int GrantPermission(AccessTokenID tokenID, const std::string& permissionName, int flag) = 0; virtual int RevokePermission(AccessTokenID tokenID, const std::string& permissionName, int flag) = 0; virtual int ClearUserGrantedPermissionState(AccessTokenID tokenID) = 0; diff --git a/interfaces/innerkits/accesstoken/src/accesstoken_manager_client.cpp b/interfaces/innerkits/accesstoken/src/accesstoken_manager_client.cpp index 44f470037..3f4ac6939 100644 --- a/interfaces/innerkits/accesstoken/src/accesstoken_manager_client.cpp +++ b/interfaces/innerkits/accesstoken/src/accesstoken_manager_client.cpp @@ -22,6 +22,7 @@ #include "iservice_registry.h" #include "native_token_info_for_sync_parcel.h" #include "native_token_info.h" +#include "permission_list_state.h" #include "permission_state_change_callback.h" namespace OHOS { @@ -145,22 +146,12 @@ PermissionOper AccessTokenManagerClient::GetSelfPermissionsState( return PASS_OPER; } - std::vector parcelList; + PermissionOper result = proxy->GetSelfPermissionsState(permList); - for (const auto& perm : permList) { - PermissionListStateParcel permParcel; - permParcel.permsState = perm; - parcelList.emplace_back(permParcel); - } - PermissionOper result = proxy->GetSelfPermissionsState(parcelList); - - if (len != parcelList.size()) { + if (len != permList.size()) { return INVALID_OPER; } - for (uint32_t i = 0; i < len; i++) { - PermissionListState perm = parcelList[i].permsState; - permList[i].state = perm.state; - } + return result; } diff --git a/interfaces/innerkits/accesstoken/src/accesstoken_manager_proxy.cpp b/interfaces/innerkits/accesstoken/src/accesstoken_manager_proxy.cpp index 0b5b01b17..166b6c4e7 100644 --- a/interfaces/innerkits/accesstoken/src/accesstoken_manager_proxy.cpp +++ b/interfaces/innerkits/accesstoken/src/accesstoken_manager_proxy.cpp @@ -18,6 +18,7 @@ #include "accesstoken_log.h" #include "parcel.h" +#include "permission_list_state_parcel.h" #include "string_ex.h" namespace OHOS { @@ -250,16 +251,20 @@ int AccessTokenManagerProxy::GetPermissionFlag(AccessTokenID tokenID, const std: } PermissionOper AccessTokenManagerProxy::GetSelfPermissionsState( - std::vector& permListParcel) + std::vector& permList) { MessageParcel data; data.WriteInterfaceToken(IAccessTokenManager::GetDescriptor()); - if (!data.WriteUint32(permListParcel.size())) { - ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to write permListParcel size."); + if (!data.WriteUint32(permList.size())) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to write permList size."); return INVALID_OPER; } - for (const auto& permission : permListParcel) { - if (!data.WriteParcelable(&permission)) { + for (const auto& perm : permList) { + + PermissionListStateParcel parcel; + + parcel.permsState = perm; + if (!data.WriteParcelable(&parcel)) { ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to write permListParcel."); return INVALID_OPER; } @@ -285,14 +290,14 @@ PermissionOper AccessTokenManagerProxy::GetSelfPermissionsState( return result; } size_t size = reply.ReadUint32(); - if (size != permListParcel.size()) { + if (size != permList.size()) { ACCESSTOKEN_LOG_ERROR(LABEL, "permListParcel size from server is invalid!"); return INVALID_OPER; } for (uint32_t i = 0; i < size; i++) { sptr permissionReq = reply.ReadParcelable(); if (permissionReq != nullptr) { - permListParcel[i].permsState.state = permissionReq->permsState.state; + permList[i].state = permissionReq->permsState.state; } } diff --git a/interfaces/innerkits/accesstoken/src/accesstoken_manager_proxy.h b/interfaces/innerkits/accesstoken/src/accesstoken_manager_proxy.h index 6177b1c6d..a9b28c27d 100644 --- a/interfaces/innerkits/accesstoken/src/accesstoken_manager_proxy.h +++ b/interfaces/innerkits/accesstoken/src/accesstoken_manager_proxy.h @@ -29,7 +29,7 @@ #include "native_token_info_for_sync_parcel.h" #include "native_token_info_parcel.h" #include "permission_def_parcel.h" -#include "permission_list_state_parcel.h" +#include "permission_list_state.h" #include "permission_state_full_parcel.h" namespace OHOS { @@ -49,7 +49,7 @@ public: int GetPermissionFlag(AccessTokenID tokenID, const std::string& permissionName) override; int GrantPermission(AccessTokenID tokenID, const std::string& permissionName, int flag) override; int RevokePermission(AccessTokenID tokenID, const std::string& permissionName, int flag) override; - PermissionOper GetSelfPermissionsState(std::vector& permList) override; + PermissionOper GetSelfPermissionsState(std::vector& permList) override; int ClearUserGrantedPermissionState(AccessTokenID tokenID) override; int GetTokenType(AccessTokenID tokenID) override; int CheckNativeDCap(AccessTokenID tokenID, const std::string& dcap) override; diff --git a/services/accesstokenmanager/main/cpp/include/permission/permission_manager.h b/services/accesstokenmanager/main/cpp/include/permission/permission_manager.h index 30f6d542a..b6af4a422 100644 --- a/services/accesstokenmanager/main/cpp/include/permission/permission_manager.h +++ b/services/accesstokenmanager/main/cpp/include/permission/permission_manager.h @@ -33,6 +33,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 +62,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/include/service/accesstoken_manager_service.h b/services/accesstokenmanager/main/cpp/include/service/accesstoken_manager_service.h index ebc754ad1..e13a530f5 100644 --- a/services/accesstokenmanager/main/cpp/include/service/accesstoken_manager_service.h +++ b/services/accesstokenmanager/main/cpp/include/service/accesstoken_manager_service.h @@ -48,7 +48,7 @@ public: int GetReqPermissions( AccessTokenID tokenID, std::vector& reqPermList, bool isSystemGrant) override; PermissionOper GetSelfPermissionsState( - std::vector& reqPermList) override; + std::vector& reqPermList) override; int GetPermissionFlag(AccessTokenID tokenID, const std::string& permissionName) override; int GrantPermission(AccessTokenID tokenID, const std::string& permissionName, int flag) override; int RevokePermission(AccessTokenID tokenID, const std::string& permissionName, int flag) override; diff --git a/services/accesstokenmanager/main/cpp/src/permission/permission_manager.cpp b/services/accesstokenmanager/main/cpp/src/permission/permission_manager.cpp index 4819bf776..5fcf7026e 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,155 @@ int32_t PermissionManager::RemovePermStateChangeCallback(const sptr& reqPermList, + int& vagueIndex, int& accurateIndex) +{ + int index = 0; + + for (const auto& perm : reqPermList) { + if (perm.permissionName == VAGUE_LOCATION_PERMISSION_NAME) { + vagueIndex = index; + } + + if (perm.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].state = vagueState; + reqPermList[accurateIndex].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]); + } else if ((vagueIndex == ELEMENT_NOT_FOUND) && (accurateIndex != ELEMENT_NOT_FOUND)) { + // only accurate location permission refuse directly + reqPermList[accurateIndex].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].permissionName.c_str(), reqPermList[vagueIndex].state); + + if (reqPermList[vagueIndex].state == DYNAMIC_OPER) { + needRes = true; + } + } + + if (accurateIndex != ELEMENT_NOT_FOUND) { + ACCESSTOKEN_LOG_INFO(LABEL, "perm: %{public}s, state: %{public}d", + reqPermList[accurateIndex].permissionName.c_str(), reqPermList[accurateIndex].state); + + if (reqPermList[accurateIndex].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..f19a07283 100644 --- a/services/accesstokenmanager/main/cpp/src/service/accesstoken_manager_service.cpp +++ b/services/accesstokenmanager/main/cpp/src/service/accesstoken_manager_service.cpp @@ -142,7 +142,7 @@ int AccessTokenManagerService::GetReqPermissions( } PermissionOper AccessTokenManagerService::GetSelfPermissionsState( - std::vector& reqPermList) + std::vector& reqPermList) { AccessTokenID callingTokenID = IPCSkeleton::GetCallingTokenID(); ACCESSTOKEN_LOG_INFO(LABEL, "callingTokenID: %{public}d", callingTokenID); @@ -158,15 +158,28 @@ PermissionOper AccessTokenManagerService::GetSelfPermissionsState( return INVALID_OPER; } + int vagueIndex = -1; + int accurateIndex = -1; + 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].permissionName == VAGUE_LOCATION_PERMISSION_NAME) || + (reqPermList[i].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) { + permsList, reqPermList[i]); + if (reqPermList[i].state == DYNAMIC_OPER) { needRes = true; } ACCESSTOKEN_LOG_INFO(LABEL, "perm: 0x%{public}s, state: 0x%{public}d", - reqPermList[i].permsState.permissionName.c_str(), reqPermList[i].permsState.state); + reqPermList[i].permissionName.c_str(), reqPermList[i].state); } if (needRes) { return DYNAMIC_OPER; diff --git a/services/accesstokenmanager/main/cpp/src/service/accesstoken_manager_stub.cpp b/services/accesstokenmanager/main/cpp/src/service/accesstoken_manager_stub.cpp index 4d4033611..dd11d54a1 100644 --- a/services/accesstokenmanager/main/cpp/src/service/accesstoken_manager_stub.cpp +++ b/services/accesstokenmanager/main/cpp/src/service/accesstoken_manager_stub.cpp @@ -18,6 +18,7 @@ #include #include "accesstoken_log.h" #include "ipc_skeleton.h" +#include "permission_list_state_parcel.h" #include "string_ex.h" namespace OHOS { @@ -121,7 +122,7 @@ void AccessTokenManagerStub::GetReqPermissionsInner(MessageParcel& data, Message void AccessTokenManagerStub::GetSelfPermissionsStateInner(MessageParcel& data, MessageParcel& reply) { - std::vector permList; + std::vector permList; uint32_t size = data.ReadUint32(); ACCESSTOKEN_LOG_INFO(LABEL, "permList size read from client data is %{public}d.", size); if (size > MAX_PERMISSION_SIZE) { @@ -132,7 +133,7 @@ void AccessTokenManagerStub::GetSelfPermissionsStateInner(MessageParcel& data, M for (uint32_t i = 0; i < size; i++) { sptr permissionParcel = data.ReadParcelable(); if (permissionParcel != nullptr) { - permList.emplace_back(*permissionParcel); + permList.emplace_back(permissionParcel->permsState); } } @@ -142,7 +143,10 @@ void AccessTokenManagerStub::GetSelfPermissionsStateInner(MessageParcel& data, M reply.WriteUint32(permList.size()); for (const auto& perm : permList) { - reply.WriteParcelable(&perm); + PermissionListStateParcel parcel; + + parcel.permsState = perm; + reply.WriteParcelable(&parcel); } } -- Gitee