diff --git a/frameworks/privacy/BUILD.gn b/frameworks/privacy/BUILD.gn index 89ff84a86..d12dc5a6e 100644 --- a/frameworks/privacy/BUILD.gn +++ b/frameworks/privacy/BUILD.gn @@ -41,6 +41,7 @@ ohos_shared_library("privacy_communication_adapter_cxx") { "src/permission_used_record_parcel.cpp", "src/permission_used_request_parcel.cpp", "src/permission_used_result_parcel.cpp", + "src/permission_used_type_info_parcel.cpp", "src/used_record_detail_parcel.cpp", ] diff --git a/frameworks/privacy/include/i_privacy_manager.h b/frameworks/privacy/include/i_privacy_manager.h index a11f711a4..f39667e18 100644 --- a/frameworks/privacy/include/i_privacy_manager.h +++ b/frameworks/privacy/include/i_privacy_manager.h @@ -27,6 +27,7 @@ #include "privacy_service_ipc_interface_code.h" #include "permission_used_request_parcel.h" #include "permission_used_result_parcel.h" +#include "permission_used_type_info_parcel.h" #ifdef SECURITY_COMPONENT_ENHANCE_ENABLE #include "sec_comp_enhance_data_parcel.h" #endif @@ -61,6 +62,8 @@ public: virtual int32_t GetSpecialSecCompEnhance(const std::string& bundleName, std::vector& enhanceParcelList) = 0; #endif + virtual int32_t GetPermissionUsedTypeInfos(const AccessTokenID tokenId, const std::string& permissionName, + std::vector& resultsParcel) = 0; }; } // namespace AccessToken } // namespace Security diff --git a/frameworks/privacy/include/permission_used_type_info_parcel.h b/frameworks/privacy/include/permission_used_type_info_parcel.h new file mode 100644 index 000000000..9916c0d6a --- /dev/null +++ b/frameworks/privacy/include/permission_used_type_info_parcel.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SECURITY_ACCESSTOKEN_PERMISSION_USED_TYPE_INFO_PARCEL_H +#define SECURITY_ACCESSTOKEN_PERMISSION_USED_TYPE_INFO_PARCEL_H + +#include "permission_used_type_info.h" + +#include "parcel.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +struct PermissionUsedTypeInfoParcel final : public Parcelable { + PermissionUsedTypeInfoParcel() = default; + + ~PermissionUsedTypeInfoParcel() override = default; + + bool Marshalling(Parcel &out) const override; + + static PermissionUsedTypeInfoParcel *Unmarshalling(Parcel &in); + + PermissionUsedTypeInfo info; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // SECURITY_ACCESSTOKEN_PERMISSION_USED_TYPE_INFO_PARCEL_H diff --git a/frameworks/privacy/include/privacy_service_ipc_interface_code.h b/frameworks/privacy/include/privacy_service_ipc_interface_code.h index f1d9c1eaf..0832ce9ea 100644 --- a/frameworks/privacy/include/privacy_service_ipc_interface_code.h +++ b/frameworks/privacy/include/privacy_service_ipc_interface_code.h @@ -36,6 +36,7 @@ enum class PrivacyInterfaceCode { GET_SEC_COMP_ENHANCE, GET_SPECIAL_SEC_COMP_ENHANCE, #endif + GET_PERMISSION_USED_TYPE_INFOS, }; } // namespace AccessToken } // namespace Security diff --git a/frameworks/privacy/src/permission_used_type_info_parcel.cpp b/frameworks/privacy/src/permission_used_type_info_parcel.cpp new file mode 100644 index 000000000..ea6ed8db6 --- /dev/null +++ b/frameworks/privacy/src/permission_used_type_info_parcel.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "permission_used_type_info_parcel.h" +#include "parcel_utils.h" +#include "refbase.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +bool PermissionUsedTypeInfoParcel::Marshalling(Parcel& out) const +{ + RETURN_IF_FALSE(out.WriteUint32(this->info.tokenId)); + RETURN_IF_FALSE(out.WriteString(this->info.permissionName)); + RETURN_IF_FALSE(out.WriteUint32(static_cast(this->info.type))); + return true; +} + +PermissionUsedTypeInfoParcel* PermissionUsedTypeInfoParcel::Unmarshalling(Parcel& in) +{ + auto* parcel = new (std::nothrow) PermissionUsedTypeInfoParcel(); + if (parcel == nullptr) { + return nullptr; + } + + RELEASE_IF_FALSE(in.ReadUint32(parcel->info.tokenId), parcel); + RELEASE_IF_FALSE(in.ReadString(parcel->info.permissionName), parcel); + uint32_t type = 0; + RELEASE_IF_FALSE(in.ReadUint32(type), parcel); + parcel->info.type = static_cast(type); + + return parcel; +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/innerkits/privacy/include/permission_used_type.h b/interfaces/innerkits/privacy/include/permission_used_type.h index 710c53191..5c5bd2a5c 100644 --- a/interfaces/innerkits/privacy/include/permission_used_type.h +++ b/interfaces/innerkits/privacy/include/permission_used_type.h @@ -43,7 +43,7 @@ namespace AccessToken { */ typedef enum PermissionUsedTypeValue { /** invalid type */ - INVALID_VISIT_TYPE = 0, + INVALID_USED_TYPE = 0, /** normal type for permision request */ NORMAL_TYPE, /** picker type for permision request */ diff --git a/interfaces/innerkits/privacy/include/permission_used_type_info.h b/interfaces/innerkits/privacy/include/permission_used_type_info.h new file mode 100644 index 000000000..8b1634726 --- /dev/null +++ b/interfaces/innerkits/privacy/include/permission_used_type_info.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @addtogroup Privacy + * @{ + * + * @brief Provides sensitive data access management. + * + * @since 9.0 + * @version 9.0 + */ + +/** + * @file permission_used_type_info.h + * + * @brief Declares PermissionUsedTypeInfo struct. + * + * @since 12.0 + * @version 12.0 + */ + +#ifndef SECURITY_ACCESSTOKEN_PERMISSION_USED_TYPE_INFO_H +#define SECURITY_ACCESSTOKEN_PERMISSION_USED_TYPE_INFO_H + +#include +#include "access_token.h" +#include "permission_used_type.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +/** + * @brief add permission used type + */ +struct PermissionUsedTypeInfo { + AccessTokenID tokenId; + std::string permissionName; + /** enum PermissionUsedType, see permission_used_type.h */ + PermissionUsedType type = NORMAL_TYPE; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // SECURITY_ACCESSTOKEN_PERMISSION_USED_TYPE_INFO_H \ No newline at end of file diff --git a/interfaces/innerkits/privacy/include/privacy_kit.h b/interfaces/innerkits/privacy/include/privacy_kit.h index e78d92950..66f350ba4 100644 --- a/interfaces/innerkits/privacy/include/privacy_kit.h +++ b/interfaces/innerkits/privacy/include/privacy_kit.h @@ -42,6 +42,7 @@ #include "on_permission_used_record_callback.h" #include "permission_used_request.h" #include "permission_used_result.h" +#include "permission_used_type_info.h" #include "perm_active_status_customized_cbk.h" #ifdef SECURITY_COMPONENT_ENHANCE_ENABLE #include "sec_comp_enhance_data.h" @@ -163,6 +164,15 @@ public: static int32_t GetSpecialSecCompEnhance(const std::string& bundleName, std::vector& enhanceList); #endif + /** + * @brief query permission used type. + * @param tokenId token id, if 0 return all tokenIds + * @param permissionName permission name, if null return all permissions + * @param results query result as PermissionUsedTypeInfo array + * @return error code, see privacy_error.h + */ + static int32_t GetPermissionUsedTypeInfos(const AccessTokenID tokenId, const std::string& permissionName, + std::vector& results); }; } // namespace AccessToken } // namespace Security diff --git a/interfaces/innerkits/privacy/libprivacy_sdk.map b/interfaces/innerkits/privacy/libprivacy_sdk.map index 5872fd10c..a2f59823b 100644 --- a/interfaces/innerkits/privacy/libprivacy_sdk.map +++ b/interfaces/innerkits/privacy/libprivacy_sdk.map @@ -41,6 +41,7 @@ "OHOS::Security::AccessToken::PermActiveStatusChangeCallback::PermActiveStatusChangeCallback(std::__h::shared_ptr const&)"; "OHOS::Security::AccessToken::StateChangeCallback::StateChangeCallback(std::__h::shared_ptr const&)"; "OHOS::Security::AccessToken::PrivacyManagerClient::InitProxy()"; + "OHOS::Security::AccessToken::PrivacyKit::GetPermissionUsedTypeInfos(unsigned int, std::__h::basic_string, std::__h::allocator> const&, std::__h::vector>&)"; ""; }; local: diff --git a/interfaces/innerkits/privacy/src/privacy_kit.cpp b/interfaces/innerkits/privacy/src/privacy_kit.cpp index b34218e9c..958d3d446 100644 --- a/interfaces/innerkits/privacy/src/privacy_kit.cpp +++ b/interfaces/innerkits/privacy/src/privacy_kit.cpp @@ -50,7 +50,8 @@ int32_t PrivacyKit::AddPermissionUsedRecord(const AddPermParamInfo& info, bool a info.tokenId, info.permissionName.c_str()); if ((!DataValidator::IsTokenIDValid(info.tokenId)) || (!DataValidator::IsPermissionNameValid(info.permissionName)) || - (info.successCount < 0 || info.failCount < 0)) { + (info.successCount < 0 || info.failCount < 0) || + (!DataValidator::IsPermissionUsedTypeValid(info.type))) { ACCESSTOKEN_LOG_ERROR(LABEL, "parameter is invalid"); return PrivacyError::ERR_PARAM_INVALID; } @@ -166,6 +167,20 @@ int32_t PrivacyKit::GetSpecialSecCompEnhance(const std::string& bundleName, GetSpecialSecCompEnhance(bundleName, enhanceList); } #endif + +int32_t PrivacyKit::GetPermissionUsedTypeInfos(const AccessTokenID tokenId, const std::string& permissionName, + std::vector& results) +{ + if (permissionName.empty()) { + return PrivacyManagerClient::GetInstance().GetPermissionUsedTypeInfos(tokenId, permissionName, results); + } + + if (!DataValidator::IsPermissionNameValid(permissionName)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "parameter is invalid"); + return PrivacyError::ERR_PARAM_INVALID; + } + return PrivacyManagerClient::GetInstance().GetPermissionUsedTypeInfos(tokenId, permissionName, results); +} } // namespace AccessToken } // namespace Security } // namespace OHOS diff --git a/interfaces/innerkits/privacy/src/privacy_manager_client.cpp b/interfaces/innerkits/privacy/src/privacy_manager_client.cpp index 8ec20fa81..9d59871e5 100644 --- a/interfaces/innerkits/privacy/src/privacy_manager_client.cpp +++ b/interfaces/innerkits/privacy/src/privacy_manager_client.cpp @@ -316,6 +316,26 @@ int32_t PrivacyManagerClient::GetSpecialSecCompEnhance(const std::string& bundle } #endif +int32_t PrivacyManagerClient::GetPermissionUsedTypeInfos(const AccessTokenID tokenId, const std::string& permissionName, + std::vector& results) +{ + auto proxy = GetProxy(); + if (proxy == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null"); + return PrivacyError::ERR_SERVICE_ABNORMAL; + } + + std::vector resultsParcel; + int32_t res = proxy->GetPermissionUsedTypeInfos(tokenId, permissionName, resultsParcel); + if (res != RET_SUCCESS) { + return res; + } + + std::transform(resultsParcel.begin(), resultsParcel.end(), std::back_inserter(results), + [](PermissionUsedTypeInfoParcel parcel) { return parcel.info; }); + return RET_SUCCESS; +} + void PrivacyManagerClient::InitProxy() { if (proxy_ == nullptr) { diff --git a/interfaces/innerkits/privacy/src/privacy_manager_client.h b/interfaces/innerkits/privacy/src/privacy_manager_client.h index 9a94dfe45..7a9ef4434 100644 --- a/interfaces/innerkits/privacy/src/privacy_manager_client.h +++ b/interfaces/innerkits/privacy/src/privacy_manager_client.h @@ -61,6 +61,8 @@ public: int32_t GetSpecialSecCompEnhance(const std::string& bundleName, std::vector& enhanceList); #endif + int32_t GetPermissionUsedTypeInfos(const AccessTokenID tokenId, const std::string& permissionName, + std::vector& results); private: PrivacyManagerClient(); diff --git a/interfaces/innerkits/privacy/src/privacy_manager_proxy.cpp b/interfaces/innerkits/privacy/src/privacy_manager_proxy.cpp index 2287388af..7e232e2c8 100644 --- a/interfaces/innerkits/privacy/src/privacy_manager_proxy.cpp +++ b/interfaces/innerkits/privacy/src/privacy_manager_proxy.cpp @@ -29,6 +29,7 @@ static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { #ifdef SECURITY_COMPONENT_ENHANCE_ENABLE static const int MAX_SEC_COMP_ENHANCE_SIZE = 1000; #endif +static const uint32_t MAX_PERMISSION_USED_TYPE_SIZE = 2000; } PrivacyManagerProxy::PrivacyManagerProxy(const sptr& impl) @@ -382,6 +383,48 @@ int32_t PrivacyManagerProxy::GetSpecialSecCompEnhance(const std::string& bundleN } #endif +int32_t PrivacyManagerProxy::GetPermissionUsedTypeInfos(const AccessTokenID tokenId, const std::string& permissionName, + std::vector& resultsParcel) +{ + MessageParcel data; + MessageParcel reply; + if (!data.WriteInterfaceToken(IPrivacyManager::GetDescriptor())) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to write WriteInterfaceToken."); + return PrivacyError::ERR_WRITE_PARCEL_FAILED; + } + if (!data.WriteUint32(tokenId)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to WriteUint32(%{public}d)", tokenId); + return false; + } + if (!data.WriteString(permissionName)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to WriteString(%{public}s)", permissionName.c_str()); + return false; + } + + if (!SendRequest(PrivacyInterfaceCode::GET_PERMISSION_USED_TYPE_INFOS, data, reply)) { + return PrivacyError::ERR_SERVICE_ABNORMAL; + } + + int32_t result = reply.ReadInt32(); + ACCESSTOKEN_LOG_INFO(LABEL, "result from server is %{public}d.", result); + if (result != RET_SUCCESS) { + return result; + } + + uint32_t size = reply.ReadUint32(); + if (size > MAX_PERMISSION_USED_TYPE_SIZE) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed, results oversize %{public}d, please add query params!", size); + return PrivacyError::ERR_OVERSIZE; + } + for (uint32_t i = 0; i < size; i++) { + sptr parcel = reply.ReadParcelable(); + if (parcel != nullptr) { + resultsParcel.emplace_back(*parcel); + } + } + return result; +} + bool PrivacyManagerProxy::SendRequest( PrivacyInterfaceCode code, MessageParcel& data, MessageParcel& reply, bool asyncMode) { diff --git a/interfaces/innerkits/privacy/src/privacy_manager_proxy.h b/interfaces/innerkits/privacy/src/privacy_manager_proxy.h index b63509998..bb20f3527 100644 --- a/interfaces/innerkits/privacy/src/privacy_manager_proxy.h +++ b/interfaces/innerkits/privacy/src/privacy_manager_proxy.h @@ -49,6 +49,8 @@ public: int32_t GetSpecialSecCompEnhance(const std::string& bundleName, std::vector& enhanceParcelList) override; #endif + int32_t GetPermissionUsedTypeInfos(const AccessTokenID tokenId, const std::string& permissionName, + std::vector& resultsParcel) override; private: bool SendRequest(PrivacyInterfaceCode code, MessageParcel& data, MessageParcel& reply, bool asyncMode = false); diff --git a/services/privacymanager/include/record/permission_record_manager.h b/services/privacymanager/include/record/permission_record_manager.h index d8a8bbf9f..9ffeb455e 100644 --- a/services/privacymanager/include/record/permission_record_manager.h +++ b/services/privacymanager/include/record/permission_record_manager.h @@ -34,6 +34,7 @@ #include "permission_record.h" #include "permission_used_request.h" #include "permission_used_result.h" +#include "permission_used_type_info.h" #include "rwlock.h" #include "thread_pool.h" #ifdef CAMERA_FLOAT_WINDOW_ENABLE @@ -88,6 +89,8 @@ public: void CallbackExecute(AccessTokenID tokenId, const std::string& permissionName, int32_t status); int32_t PermissionListFilter(const std::vector& listSrc, std::vector& listRes); bool IsAllowedUsingPermission(AccessTokenID tokenId, const std::string& permissionName); + int32_t GetPermissionUsedTypeInfos(AccessTokenID tokenId, const std::string& permissionName, + std::vector& results); void NotifyMicChange(bool switchStatus); void NotifyCameraChange(bool switchStatus); @@ -137,10 +140,11 @@ private: void ExecuteCameraCallbackAsync(AccessTokenID tokenId); void SetCameraCallback(sptr); - void GenerateNewUsedType(const PermissionUsedType type, int32_t& dataType); + void TransformEnumToBitValue(const PermissionUsedType type, int32_t& value); bool AddOrUpdateUsedTypeIfNeeded(const AccessTokenID tokenId, const int32_t opCode, const PermissionUsedType type); void RemovePermissionUsedType(AccessTokenID tokenId); + void AddDataValueToResults(const GenericValues value, std::vector& results); #ifdef CAMERA_FLOAT_WINDOW_ENABLE bool IsFlowWindowShow(AccessTokenID tokenId); diff --git a/services/privacymanager/include/service/privacy_manager_service.h b/services/privacymanager/include/service/privacy_manager_service.h index ff9f6d6a3..c715f3240 100644 --- a/services/privacymanager/include/service/privacy_manager_service.h +++ b/services/privacymanager/include/service/privacy_manager_service.h @@ -62,6 +62,8 @@ public: std::vector& enhanceParcelList) override; #endif bool IsAllowedUsingPermission(AccessTokenID tokenId, const std::string& permissionName) override; + int32_t GetPermissionUsedTypeInfos(AccessTokenID tokenId, const std::string& permissionName, + std::vector& resultsParcel) override; int32_t Dump(int32_t fd, const std::vector& args) override; private: #ifdef POWER_MANAGER_ENABLE diff --git a/services/privacymanager/include/service/privacy_manager_stub.h b/services/privacymanager/include/service/privacy_manager_stub.h index af216a3a4..f9184ef6a 100644 --- a/services/privacymanager/include/service/privacy_manager_stub.h +++ b/services/privacymanager/include/service/privacy_manager_stub.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Copyright (c) 2022-2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -16,6 +16,8 @@ #ifndef PRIVACY_MANAGER_STUB_H #define PRIVACY_MANAGER_STUB_H +#include + #include "i_privacy_manager.h" #include "iremote_stub.h" #include "nocopyable.h" @@ -25,7 +27,7 @@ namespace Security { namespace AccessToken { class PrivacyManagerStub : public IRemoteStub { public: - PrivacyManagerStub() = default; + PrivacyManagerStub(); virtual ~PrivacyManagerStub() = default; int32_t OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel& reply, MessageOption& option) override; @@ -48,6 +50,7 @@ private: void GetSpecialSecCompEnhanceInner(MessageParcel& data, MessageParcel& reply); bool IsSecCompServiceCalling(); #endif + void GetPermissionUsedTypeInfosInner(MessageParcel& data, MessageParcel& reply); bool IsAccessTokenCalling() const; bool IsSystemAppCalling() const; bool VerifyPermission(const std::string& permission) const; @@ -55,6 +58,10 @@ private: #ifdef SECURITY_COMPONENT_ENHANCE_ENABLE AccessTokenID secCompTokenId_ = 0; #endif + void SetPrivacyFuncInMap(); + + using RequestType = void (PrivacyManagerStub::*)(MessageParcel &data, MessageParcel &reply); + std::map requestMap_; }; } // namespace AccessToken } // namespace Security diff --git a/services/privacymanager/src/record/permission_record_manager.cpp b/services/privacymanager/src/record/permission_record_manager.cpp index cc98af00c..79c22a1b7 100644 --- a/services/privacymanager/src/record/permission_record_manager.cpp +++ b/services/privacymanager/src/record/permission_record_manager.cpp @@ -185,20 +185,23 @@ int32_t PermissionRecordManager::GetPermissionRecord(AccessTokenID tokenId, cons return Constant::SUCCESS; } -void PermissionRecordManager::GenerateNewUsedType(const PermissionUsedType type, int32_t& dataType) +void PermissionRecordManager::TransformEnumToBitValue(const PermissionUsedType type, int32_t& value) { if (type == PermissionUsedType::NORMAL_TYPE) { - dataType |= NORMAL_TYPE_ADD_VALUE; + value = NORMAL_TYPE_ADD_VALUE; } else if (type == PermissionUsedType::PICKER_TYPE) { - dataType |= PICKER_TYPE_ADD_VALUE; + value = PICKER_TYPE_ADD_VALUE; } else if (type == PermissionUsedType::SECURITY_COMPONENT_TYPE) { - dataType |= SEC_COMPONENT_TYPE_ADD_VALUE; + value = SEC_COMPONENT_TYPE_ADD_VALUE; } } bool PermissionRecordManager::AddOrUpdateUsedTypeIfNeeded(const AccessTokenID tokenId, const int32_t opCode, const PermissionUsedType type) { + int32_t inputType = 0; + TransformEnumToBitValue(type, inputType); + GenericValues conditionValue; conditionValue.Put(PrivacyFiledConst::FIELD_TOKEN_ID, static_cast(tokenId)); conditionValue.Put(PrivacyFiledConst::FIELD_PERMISSION_CODE, opCode); @@ -216,7 +219,7 @@ bool PermissionRecordManager::AddOrUpdateUsedTypeIfNeeded(const AccessTokenID to GenericValues recordValue; recordValue.Put(PrivacyFiledConst::FIELD_TOKEN_ID, static_cast(tokenId)); recordValue.Put(PrivacyFiledConst::FIELD_PERMISSION_CODE, opCode); - recordValue.Put(PrivacyFiledConst::FIELD_USED_TYPE, static_cast(type)); + recordValue.Put(PrivacyFiledConst::FIELD_USED_TYPE, static_cast(inputType)); std::vector recordValues; recordValues.emplace_back(recordValue); @@ -226,11 +229,10 @@ bool PermissionRecordManager::AddOrUpdateUsedTypeIfNeeded(const AccessTokenID to } } else { // not empty means there is permission used type record exsit, update it if needed - ACCESSTOKEN_LOG_DEBUG(LABEL, "record exsit."); + int32_t dbType = results[0].GetInt(PrivacyFiledConst::FIELD_USED_TYPE); + ACCESSTOKEN_LOG_DEBUG(LABEL, "record exsit, type is %{public}d.", dbType); - int32_t inputType = static_cast(type); - int32_t dataType = results[0].GetInt(PrivacyFiledConst::FIELD_USED_TYPE); - if ((dataType & inputType) == inputType) { + if ((dbType & inputType) == inputType) { // true means visitTypeEnum has exsits, no need to add ACCESSTOKEN_LOG_DEBUG(LABEL, "used type has add"); return true; @@ -239,10 +241,10 @@ bool PermissionRecordManager::AddOrUpdateUsedTypeIfNeeded(const AccessTokenID to ACCESSTOKEN_LOG_DEBUG(LABEL, "used type not add"); results[0].Remove(PrivacyFiledConst::FIELD_USED_TYPE); - GenerateNewUsedType(type, dataType); + dbType |= inputType; GenericValues newValue; - newValue.Put(PrivacyFiledConst::FIELD_USED_TYPE, dataType); + newValue.Put(PrivacyFiledConst::FIELD_USED_TYPE, dbType); return PermissionRecordRepository::GetInstance().Update( PermissionUsedRecordDb::DataType::PERMISSION_USED_TYPE, newValue, results[0]); } @@ -1005,6 +1007,66 @@ int32_t PermissionRecordManager::UnRegisterPermActiveStatusCallback(const sptr& results) +{ + PermissionUsedTypeInfo info; + info.tokenId = static_cast(value.GetInt(PrivacyFiledConst::FIELD_TOKEN_ID)); + Constant::TransferOpcodeToPermission(value.GetInt(PrivacyFiledConst::FIELD_PERMISSION_CODE), info.permissionName); + int32_t type = value.GetInt(PrivacyFiledConst::FIELD_USED_TYPE); + + if ((type & NORMAL_TYPE_ADD_VALUE) == NORMAL_TYPE_ADD_VALUE) { // normal first + info.type = PermissionUsedType::NORMAL_TYPE; + results.emplace_back(info); + } + if ((type & PICKER_TYPE_ADD_VALUE) == PICKER_TYPE_ADD_VALUE) { // picker second + info.type = PermissionUsedType::PICKER_TYPE; + results.emplace_back(info); + } + if ((type & SEC_COMPONENT_TYPE_ADD_VALUE) == SEC_COMPONENT_TYPE_ADD_VALUE) { // security component last + info.type = PermissionUsedType::SECURITY_COMPONENT_TYPE; + results.emplace_back(info); + } +} + +int32_t PermissionRecordManager::GetPermissionUsedTypeInfos(AccessTokenID tokenId, const std::string& permissionName, + std::vector& results) +{ + GenericValues value; + + if (tokenId != INVALID_TOKENID) { + HapTokenInfo tokenInfo; + if (AccessTokenKit::GetHapTokenInfo(tokenId, tokenInfo) != Constant::SUCCESS) { + ACCESSTOKEN_LOG_ERROR(LABEL, "invalid tokenId(%{public}d)", tokenId); + return PrivacyError::ERR_TOKENID_NOT_EXIST; + } + value.Put(PrivacyFiledConst::FIELD_TOKEN_ID, static_cast(tokenId)); + } + + if (!permissionName.empty()) { + int32_t opCode; + if (!Constant::TransferPermissionToOpcode(permissionName, opCode)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "invalid (%{public}s)", permissionName.c_str()); + return PrivacyError::ERR_PERMISSION_NOT_EXIST; + } + value.Put(PrivacyFiledConst::FIELD_PERMISSION_CODE, opCode); + } + + std::vector valueResults; + if (!PermissionRecordRepository::GetInstance().Query( + PermissionUsedRecordDb::DataType::PERMISSION_USED_TYPE, value, valueResults)) { + return Constant::FAILURE; + } + + for (const auto& valueResult : valueResults) { + AddDataValueToResults(valueResult, results); + } + + ACCESSTOKEN_LOG_INFO(LABEL, "get %{public}zu permission used type records", results.size()); + + return Constant::SUCCESS; +} + std::string PermissionRecordManager::GetDeviceId(AccessTokenID tokenId) { HapTokenInfo tokenInfo; diff --git a/services/privacymanager/src/service/privacy_manager_service.cpp b/services/privacymanager/src/service/privacy_manager_service.cpp index e7d28001a..3d64932bf 100644 --- a/services/privacymanager/src/service/privacy_manager_service.cpp +++ b/services/privacymanager/src/service/privacy_manager_service.cpp @@ -274,6 +274,26 @@ bool PrivacyManagerService::IsAllowedUsingPermission(AccessTokenID tokenId, cons return PermissionRecordManager::GetInstance().IsAllowedUsingPermission(tokenId, permissionName); } +int32_t PrivacyManagerService::GetPermissionUsedTypeInfos(AccessTokenID tokenId, const std::string& permissionName, + std::vector& resultsParcel) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "tokenId: %{public}d, permissionName: %{public}s", tokenId, permissionName.c_str()); + + std::vector results; + int32_t res = PermissionRecordManager::GetInstance().GetPermissionUsedTypeInfos(tokenId, permissionName, results); + if (res != RET_SUCCESS) { + return res; + } + + for (const auto& result : results) { + PermissionUsedTypeInfoParcel parcel; + parcel.info = result; + resultsParcel.emplace_back(parcel); + } + + return RET_SUCCESS; +} + #ifdef POWER_MANAGER_ENABLE void PrivacyManagerService::OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId) { diff --git a/services/privacymanager/src/service/privacy_manager_stub.cpp b/services/privacymanager/src/service/privacy_manager_stub.cpp index 2e9968f2c..180ef8d8f 100644 --- a/services/privacymanager/src/service/privacy_manager_stub.cpp +++ b/services/privacymanager/src/service/privacy_manager_stub.cpp @@ -34,6 +34,44 @@ static const uint32_t PERM_LIST_SIZE_MAX = 1024; static const std::string PERMISSION_USED_STATS = "ohos.permission.PERMISSION_USED_STATS"; } +PrivacyManagerStub::PrivacyManagerStub() +{ + SetPrivacyFuncInMap(); +} + +void PrivacyManagerStub::SetPrivacyFuncInMap() +{ + requestMap_[static_cast(PrivacyInterfaceCode::ADD_PERMISSION_USED_RECORD)] = + &PrivacyManagerStub::AddPermissionUsedRecordInner; + requestMap_[static_cast(PrivacyInterfaceCode::START_USING_PERMISSION)] = + &PrivacyManagerStub::StartUsingPermissionInner; + requestMap_[static_cast(PrivacyInterfaceCode::START_USING_PERMISSION_CALLBACK)] = + &PrivacyManagerStub::StartUsingPermissionCallbackInner; + requestMap_[static_cast(PrivacyInterfaceCode::STOP_USING_PERMISSION)] = + &PrivacyManagerStub::StopUsingPermissionInner; + requestMap_[static_cast(PrivacyInterfaceCode::DELETE_PERMISSION_USED_RECORDS)] = + &PrivacyManagerStub::RemovePermissionUsedRecordsInner; + requestMap_[static_cast(PrivacyInterfaceCode::GET_PERMISSION_USED_RECORDS)] = + &PrivacyManagerStub::GetPermissionUsedRecordsInner; + requestMap_[static_cast(PrivacyInterfaceCode::GET_PERMISSION_USED_RECORDS_ASYNC)] = + &PrivacyManagerStub::GetPermissionUsedRecordsAsyncInner; + requestMap_[static_cast(PrivacyInterfaceCode::REGISTER_PERM_ACTIVE_STATUS_CHANGE_CALLBACK)] = + &PrivacyManagerStub::RegisterPermActiveStatusCallbackInner; + requestMap_[static_cast(PrivacyInterfaceCode::UNREGISTER_PERM_ACTIVE_STATUS_CHANGE_CALLBACK)] = + &PrivacyManagerStub::UnRegisterPermActiveStatusCallbackInner; + requestMap_[static_cast(PrivacyInterfaceCode::IS_ALLOWED_USING_PERMISSION)] = + &PrivacyManagerStub::IsAllowedUsingPermissionInner; +#ifdef SECURITY_COMPONENT_ENHANCE_ENABLE + requestMap_[static_cast(PrivacyInterfaceCode::REGISTER_SEC_COMP_ENHANCE)] = + &PrivacyManagerStub::RegisterSecCompEnhanceInner; + requestMap_[static_cast(PrivacyInterfaceCode::GET_SEC_COMP_ENHANCE)] = + &PrivacyManagerStub::GetSecCompEnhanceInner; + requestMap_[static_cast(PrivacyInterfaceCode::GET_SPECIAL_SEC_COMP_ENHANCE)] = + &PrivacyManagerStub::GetSpecialSecCompEnhanceInner; +#endif + requestMap_[static_cast(PrivacyInterfaceCode::GET_PERMISSION_USED_TYPE_INFOS)] = + &PrivacyManagerStub::GetPermissionUsedTypeInfosInner; +} int32_t PrivacyManagerStub::OnRemoteRequest( uint32_t code, MessageParcel& data, MessageParcel& reply, MessageOption& option) { @@ -43,47 +81,17 @@ int32_t PrivacyManagerStub::OnRemoteRequest( ACCESSTOKEN_LOG_ERROR(LABEL, "get unexpect descriptor: %{public}s", Str16ToStr8(descriptor).c_str()); return ERROR_IPC_REQUEST_FAIL; } - switch (code) { - case static_cast(PrivacyInterfaceCode::ADD_PERMISSION_USED_RECORD): - AddPermissionUsedRecordInner(data, reply); - break; - case static_cast(PrivacyInterfaceCode::START_USING_PERMISSION): - StartUsingPermissionInner(data, reply); - break; - case static_cast(PrivacyInterfaceCode::START_USING_PERMISSION_CALLBACK): - StartUsingPermissionCallbackInner(data, reply); - break; - case static_cast(PrivacyInterfaceCode::STOP_USING_PERMISSION): - StopUsingPermissionInner(data, reply); - break; - case static_cast(PrivacyInterfaceCode::DELETE_PERMISSION_USED_RECORDS): - RemovePermissionUsedRecordsInner(data, reply); - break; - case static_cast(PrivacyInterfaceCode::GET_PERMISSION_USED_RECORDS): - GetPermissionUsedRecordsInner(data, reply); - break; - case static_cast(PrivacyInterfaceCode::GET_PERMISSION_USED_RECORDS_ASYNC): - GetPermissionUsedRecordsAsyncInner(data, reply); - break; - case static_cast(PrivacyInterfaceCode::REGISTER_PERM_ACTIVE_STATUS_CHANGE_CALLBACK): - RegisterPermActiveStatusCallbackInner(data, reply); - break; - case static_cast( - PrivacyInterfaceCode::UNREGISTER_PERM_ACTIVE_STATUS_CHANGE_CALLBACK): - UnRegisterPermActiveStatusCallbackInner(data, reply); - break; - case static_cast(PrivacyInterfaceCode::IS_ALLOWED_USING_PERMISSION): - IsAllowedUsingPermissionInner(data, reply); - break; - default: -#ifdef SECURITY_COMPONENT_ENHANCE_ENABLE - if (HandleSecCompReq(code, data, reply)) { - return NO_ERROR; - } -#endif - return IPCObjectStub::OnRemoteRequest(code, data, reply, option); + + auto itFunc = requestMap_.find(code); + if (itFunc != requestMap_.end()) { + auto requestFunc = itFunc->second; + if (requestFunc != nullptr) { + (this->*requestFunc)(data, reply); + return NO_ERROR; + } } - return NO_ERROR; + + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); } void PrivacyManagerStub::AddPermissionUsedRecordInner(MessageParcel& data, MessageParcel& reply) @@ -367,6 +375,31 @@ bool PrivacyManagerStub::IsSecCompServiceCalling() } #endif +void PrivacyManagerStub::GetPermissionUsedTypeInfosInner(MessageParcel& data, MessageParcel& reply) +{ + uint32_t callingTokenID = IPCSkeleton::GetCallingTokenID(); + if ((AccessTokenKit::GetTokenTypeFlag(callingTokenID) == TOKEN_HAP) && (!IsSystemAppCalling())) { + reply.WriteInt32(PrivacyError::ERR_NOT_SYSTEM_APP); + return; + } + if (!VerifyPermission(PERMISSION_USED_STATS)) { + reply.WriteInt32(PrivacyError::ERR_PERMISSION_DENIED); + return; + } + AccessTokenID tokenId = data.ReadUint32(); + std::string permissionName = data.ReadString(); + std::vector resultsParcel; + int32_t result = this->GetPermissionUsedTypeInfos(tokenId, permissionName, resultsParcel); + if (!reply.WriteInt32(result)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to WriteInt32(%{public}d-%{public}s)", tokenId, permissionName.c_str()); + return; + } + reply.WriteUint32(resultsParcel.size()); + for (const auto& parcel : resultsParcel) { + reply.WriteParcelable(&parcel); + } +} + bool PrivacyManagerStub::IsAccessTokenCalling() const { int32_t callingUid = IPCSkeleton::GetCallingUid(); diff --git a/services/privacymanager/test/unittest/privacy_manager_service_test.cpp b/services/privacymanager/test/unittest/privacy_manager_service_test.cpp index d9b0015a3..71badb306 100644 --- a/services/privacymanager/test/unittest/privacy_manager_service_test.cpp +++ b/services/privacymanager/test/unittest/privacy_manager_service_test.cpp @@ -289,6 +289,11 @@ public: { return true; } + int32_t GetPermissionUsedTypeInfos(const AccessTokenID tokenId, const std::string& permissionName, + std::vector& resultsParcel) + { + return RET_SUCCESS; + } #ifdef SECURITY_COMPONENT_ENHANCE_ENABLE int32_t RegisterSecCompEnhance(const SecCompEnhanceDataParcel& enhanceParcel) {