add add startUsingWithBundle

Co-Authored-By: Agent

Signed-off-by: chennian <chennian1@huawei.com>
Change-Id: I9ad63b8a72ed9cf7911df35ee05869fca5bd8833
This commit is contained in:
chennian
2026-03-16 20:57:41 +08:00
parent f9aae10b76
commit 499cf76fec
52 changed files with 2967 additions and 239 deletions
+7
View File
@@ -203,3 +203,10 @@ if ("${target_platform}" == "pc" || "${target_platform}" == "tablet" || use_libf
} else {
access_token_manage_user_policy_enable = false
}
if ("${target_platform}" == "phone" || "${target_platform}" == "tablet" || "${target_platform}" == "pc") {
privacy_bundle_start_stop_enable = true
access_token_cflags_cc += [ "-DPRIVACY_BUNDLE_START_STOP_ENABLE" ]
} else {
privacy_bundle_start_stop_enable = false
}
@@ -31,6 +31,7 @@ bool ActiveChangeResponseParcel::Marshalling(Parcel& out) const
RETURN_IF_FALSE(out.WriteString(this->changeResponse.deviceId));
RETURN_IF_FALSE(out.WriteString(this->changeResponse.remoteDeviceName));
RETURN_IF_FALSE(out.WriteString(this->changeResponse.extra));
RETURN_IF_FALSE(out.WriteString(this->changeResponse.bundleName));
return true;
}
@@ -61,6 +62,8 @@ ActiveChangeResponseParcel* ActiveChangeResponseParcel::Unmarshalling(Parcel& in
RELEASE_IF_FALSE(
in.ReadString(activeChangeResponseParcel->changeResponse.remoteDeviceName), activeChangeResponseParcel);
RELEASE_IF_FALSE(in.ReadString(activeChangeResponseParcel->changeResponse.extra), activeChangeResponseParcel);
RELEASE_IF_FALSE(
in.ReadString(activeChangeResponseParcel->changeResponse.bundleName), activeChangeResponseParcel);
return activeChangeResponseParcel;
}
} // namespace AccessToken
@@ -164,18 +164,17 @@ HWTEST_F(PrivacyParcelTest, ActiveChangeResponseParcel001, TestSize.Level1)
{
ActiveChangeResponseParcel activeChangeResponseParcel;
activeChangeResponseParcel.changeResponse = {
.callingTokenID = 100,
.tokenID = 100,
.permissionName = "ohos.permission.CAMERA",
.type = PERM_INACTIVE,
.usedType = NORMAL_TYPE,
.pid = -1,
.isRemote = false,
.deviceId = "device",
.remoteDeviceName = "name",
.extra = "perm_add",
};
activeChangeResponseParcel.changeResponse.callingTokenID = 100;
activeChangeResponseParcel.changeResponse.tokenID = 100;
activeChangeResponseParcel.changeResponse.permissionName = "ohos.permission.CAMERA";
activeChangeResponseParcel.changeResponse.type = PERM_INACTIVE;
activeChangeResponseParcel.changeResponse.usedType = NORMAL_TYPE;
activeChangeResponseParcel.changeResponse.pid = -1;
activeChangeResponseParcel.changeResponse.isRemote = false;
activeChangeResponseParcel.changeResponse.deviceId = "device";
activeChangeResponseParcel.changeResponse.remoteDeviceName = "name";
activeChangeResponseParcel.changeResponse.extra = "perm_add";
activeChangeResponseParcel.changeResponse.bundleName = "com.ohos.permissionmanager";
Parcel parcel;
EXPECT_EQ(true, activeChangeResponseParcel.Marshalling(parcel));
@@ -193,6 +192,7 @@ HWTEST_F(PrivacyParcelTest, ActiveChangeResponseParcel001, TestSize.Level1)
EXPECT_EQ(activeChangeResponseParcel.changeResponse.deviceId, readedData->changeResponse.deviceId);
EXPECT_EQ(activeChangeResponseParcel.changeResponse.remoteDeviceName, readedData->changeResponse.remoteDeviceName);
EXPECT_EQ(activeChangeResponseParcel.changeResponse.extra, readedData->changeResponse.extra);
EXPECT_EQ(activeChangeResponseParcel.changeResponse.bundleName, readedData->changeResponse.bundleName);
}
/**
@@ -68,21 +68,47 @@ enum LockScreenStatusChangeType {
* @brief Permission active state change response struct
*/
struct ActiveChangeResponse {
AccessTokenID callingTokenID = 0;
AccessTokenID tokenID = 0;
AccessTokenID callingTokenID = INVALID_TOKENID;
AccessTokenID tokenID = INVALID_TOKENID;
std::string permissionName;
/**
* permission active change type, for details about the valid values,
* see the definition above.
*/
ActiveChangeType type;
PermissionUsedType usedType;
ActiveChangeType type = PERM_INACTIVE;
PermissionUsedType usedType = NORMAL_TYPE;
int32_t pid = -1;
bool isRemote = false;
std::string deviceId;
std::string remoteDeviceName;
/** extra info propagated from AddPermParamInfo::extra for PERM_ADD callback */
std::string extra = "";
/**
* This field is only filled in callbacks triggered by bundle-based start/stop using permission.
* The callback contains the bundle name, permission name of this access.
*/
std::string bundleName;
ActiveChangeResponse() = default;
// Used by token-based active records and current-using queries.
ActiveChangeResponse(AccessTokenID callingTokenID, AccessTokenID tokenID, const std::string& permissionName,
ActiveChangeType type, PermissionUsedType usedType, int32_t pid = -1)
: callingTokenID(callingTokenID), tokenID(tokenID), permissionName(permissionName), type(type),
usedType(usedType), pid(pid)
{}
// Used by bundle-based current-using queries.
ActiveChangeResponse(const std::string& bundleName, const std::string& permissionName)
: permissionName(permissionName), type(PERM_ACTIVE_IN_FOREGROUND), bundleName(bundleName)
{}
// Used by remote permission active records and callbacks.
ActiveChangeResponse(const std::string& permissionName, const std::string& deviceId,
const std::string& remoteDeviceName)
: permissionName(permissionName), type(PERM_REMOTE_USING), isRemote(true), deviceId(deviceId),
remoteDeviceName(remoteDeviceName)
{}
};
typedef ActiveChangeResponse CurrUsingPermInfo;
@@ -117,6 +117,20 @@ public:
* @return error code, see privacy_error.h
*/
static int32_t StopUsingPermission(AccessTokenID tokenID, const std::string& permissionName, int32_t pid = -1);
/**
* @brief Input bundleName start using input permission.
* @param bundleName bundle name
* @param permissionName permission name
* @return error code, see privacy_error.h
*/
static int32_t StartUsingPermission(const std::string& bundleName, const std::string& permissionName);
/**
* @brief Input bundleName stop using input permission.
* @param bundleName bundle name
* @param permissionName permission name
* @return error code, see privacy_error.h
*/
static int32_t StopUsingPermission(const std::string& bundleName, const std::string& permissionName);
/**
* @brief Input info start remote using input permission.
* @param info caller info
@@ -178,9 +192,11 @@ public:
/**
* @brief Register sensitive permission active status change callback.
* @param callback PermActiveStatusCustomizedCbk smark pointer quote
* @param type callback register type, default is TOKEN_ONLY
* @return error code, see privacy_error.h
*/
static int32_t RegisterPermActiveStatusCallback(const std::shared_ptr<PermActiveStatusCustomizedCbk>& callback);
static int32_t RegisterPermActiveStatusCallback(const std::shared_ptr<PermActiveStatusCustomizedCbk>& callback,
CallbackRegisterType type = CallbackRegisterType::TOKEN_ONLY);
/**
* @brief Unregister sensitive permission active status change callback.
* @param callback PermActiveStatusCustomizedCbk smark pointer quote
@@ -58,6 +58,11 @@ enum CallerType {
MICROPHONE = 0,
CAMERA = 1
};
enum class CallbackRegisterType {
ALL = 0,
TOKEN_ONLY,
};
} // namespace AccessToken
} // namespace Security
} // namespace OHOS
@@ -22,13 +22,15 @@
"OHOS::Security::AccessToken::PrivacyKit::GetPermissionUsedRecordToggleStatus(int, bool&)";
"OHOS::Security::AccessToken::PrivacyKit::StartUsingPermission(unsigned int, std::__h::basic_string<char, std::__h::char_traits<char>, std::__h::allocator<char>> const&, int, OHOS::Security::AccessToken::PermissionUsedTypeValue)";
"OHOS::Security::AccessToken::PrivacyKit::StopUsingPermission(unsigned int, std::__h::basic_string<char, std::__h::char_traits<char>, std::__h::allocator<char>> const&, int)";
"OHOS::Security::AccessToken::PrivacyKit::StartUsingPermission(std::__h::basic_string<char, std::__h::char_traits<char>, std::__h::allocator<char>> const&, std::__h::basic_string<char, std::__h::char_traits<char>, std::__h::allocator<char>> const&)";
"OHOS::Security::AccessToken::PrivacyKit::StopUsingPermission(std::__h::basic_string<char, std::__h::char_traits<char>, std::__h::allocator<char>> const&, std::__h::basic_string<char, std::__h::char_traits<char>, std::__h::allocator<char>> const&)";
"OHOS::Security::AccessToken::PrivacyKit::StartRemoteUsingPermission(OHOS::Security::AccessToken::RemoteCallerInfo const&, std::__h::basic_string<char, std::__h::char_traits<char>, std::__h::allocator<char>> const&)";
"OHOS::Security::AccessToken::PrivacyKit::StopRemoteUsingPermission(OHOS::Security::AccessToken::RemoteCallerInfo const&, std::__h::basic_string<char, std::__h::char_traits<char>, std::__h::allocator<char>> const&)";
"OHOS::Security::AccessToken::PrivacyKit::GetPermissionUsedRecords(OHOS::Security::AccessToken::PermissionUsedRequest const&, OHOS::Security::AccessToken::PermissionUsedResult&)";
"OHOS::Security::AccessToken::PrivacyKit::AddRemotePermissionUsedRecord(OHOS::Security::AccessToken::RemoteCallerInfo const&, std::__h::basic_string<char, std::__h::char_traits<char>, std::__h::allocator<char>> const&, int, int, bool)";
"OHOS::Security::AccessToken::PrivacyKit::GetRemotePermissionUsedRecords(OHOS::Security::AccessToken::PermissionUsedRequest const&, OHOS::Security::AccessToken::PermissionUsedResult&)";
"OHOS::Security::AccessToken::PermActiveStatusCustomizedCbk::GetPermList(std::__h::vector<std::__h::basic_string<char, std::__h::char_traits<char>, std::__h::allocator<char>>, std::__h::allocator<std::__h::basic_string<char, std::__h::char_traits<char>, std::__h::allocator<char>>>>&) const";
"OHOS::Security::AccessToken::PrivacyKit::RegisterPermActiveStatusCallback(std::__h::shared_ptr<OHOS::Security::AccessToken::PermActiveStatusCustomizedCbk> const&)";
"OHOS::Security::AccessToken::PrivacyKit::RegisterPermActiveStatusCallback(std::__h::shared_ptr<OHOS::Security::AccessToken::PermActiveStatusCustomizedCbk> const&, OHOS::Security::AccessToken::CallbackRegisterType)";
"OHOS::Security::AccessToken::PrivacyKit::UnRegisterPermActiveStatusCallback(std::__h::shared_ptr<OHOS::Security::AccessToken::PermActiveStatusCustomizedCbk> const&)";
"OHOS::Security::AccessToken::PrivacyKit::RemovePermissionUsedRecords(unsigned int)";
"OHOS::Security::AccessToken::StateCustomizedCbk::StateCustomizedCbk()";
@@ -38,7 +40,7 @@
"OHOS::Security::AccessToken::StateCustomizedCbk::~StateCustomizedCbk()";
"OHOS::Security::AccessToken::OnPermissionUsedRecordCallbackStub::OnRemoteRequest(unsigned int, OHOS::MessageParcel&, OHOS::MessageParcel&, OHOS::MessageOption&)";
"OHOS::Security::AccessToken::PrivacyManagerClient::GetInstance()";
"OHOS::Security::AccessToken::PrivacyManagerClient::RegisterPermActiveStatusCallback(std::__h::shared_ptr<OHOS::Security::AccessToken::PermActiveStatusCustomizedCbk> const&)";
"OHOS::Security::AccessToken::PrivacyManagerClient::RegisterPermActiveStatusCallback(std::__h::shared_ptr<OHOS::Security::AccessToken::PermActiveStatusCustomizedCbk> const&, OHOS::Security::AccessToken::CallbackRegisterType)";
"OHOS::Security::AccessToken::StateChangeCallbackStub::OnRemoteRequest(unsigned int, OHOS::MessageParcel&, OHOS::MessageParcel&, OHOS::MessageOption&)";
"OHOS::Security::AccessToken::PermActiveStatusChangeCallbackStub::OnRemoteRequest(unsigned int, OHOS::MessageParcel&, OHOS::MessageParcel&, OHOS::MessageOption&)";
"OHOS::Security::AccessToken::PermActiveStatusChangeCallback::PermActiveStatusChangeCallback(std::__h::shared_ptr<OHOS::Security::AccessToken::PermActiveStatusCustomizedCbk> const&)";
@@ -29,6 +29,11 @@ namespace Security {
namespace AccessToken {
namespace {
constexpr const int64_t MERGE_TIMESTAMP = 200; // 200ms
bool IsValidCallbackRegisterType(CallbackRegisterType type)
{
return (type == CallbackRegisterType::ALL) || (type == CallbackRegisterType::TOKEN_ONLY);
}
std::mutex g_lockCache;
struct RecordCache {
int32_t successCount = 0;
@@ -162,6 +167,30 @@ int32_t PrivacyKit::StopUsingPermission(AccessTokenID tokenID, const std::string
return PrivacyManagerClient::GetInstance().StopUsingPermission(tokenID, pid, permissionName);
}
int32_t PrivacyKit::StartUsingPermission(const std::string& bundleName, const std::string& permissionName)
{
#ifndef PRIVACY_BUNDLE_START_STOP_ENABLE
return PrivacyError::ERR_CAPABILITY_NOT_SUPPORT;
#else
if (!DataValidator::IsBundleNameValid(bundleName) || !DataValidator::IsPermissionNameValid(permissionName)) {
return PrivacyError::ERR_PARAM_INVALID;
}
return PrivacyManagerClient::GetInstance().StartUsingPermission(bundleName, permissionName);
#endif
}
int32_t PrivacyKit::StopUsingPermission(const std::string& bundleName, const std::string& permissionName)
{
#ifndef PRIVACY_BUNDLE_START_STOP_ENABLE
return PrivacyError::ERR_CAPABILITY_NOT_SUPPORT;
#else
if (!DataValidator::IsBundleNameValid(bundleName) || !DataValidator::IsPermissionNameValid(permissionName)) {
return PrivacyError::ERR_PARAM_INVALID;
}
return PrivacyManagerClient::GetInstance().StopUsingPermission(bundleName, permissionName);
#endif
}
int32_t PrivacyKit::RemovePermissionUsedRecords(AccessTokenID tokenID)
{
if (!DataValidator::IsTokenIDValid(tokenID)) {
@@ -306,9 +335,13 @@ int32_t PrivacyKit::GetRemotePermissionUsedRecords(
}
#endif
int32_t PrivacyKit::RegisterPermActiveStatusCallback(const std::shared_ptr<PermActiveStatusCustomizedCbk>& callback)
int32_t PrivacyKit::RegisterPermActiveStatusCallback(
const std::shared_ptr<PermActiveStatusCustomizedCbk>& callback, CallbackRegisterType type)
{
return PrivacyManagerClient::GetInstance().RegisterPermActiveStatusCallback(callback);
if (!IsValidCallbackRegisterType(type)) {
return PrivacyError::ERR_PARAM_INVALID;
}
return PrivacyManagerClient::GetInstance().RegisterPermActiveStatusCallback(callback, type);
}
int32_t PrivacyKit::UnRegisterPermActiveStatusCallback(const std::shared_ptr<PermActiveStatusCustomizedCbk>& callback)
@@ -155,6 +155,9 @@ void PrivacyManagerClient::OnAddPrivacySa(void)
{
LOGI(PRI_DOMAIN, PRI_TAG, "Enter.");
ReStartUsing();
#ifdef PRIVACY_BUNDLE_START_STOP_ENABLE
ReStartUsingBundle();
#endif
#ifdef REMOTE_PRIVACY_ENABLE
ReStartRemoteUsing();
#endif
@@ -492,6 +495,92 @@ int32_t PrivacyManagerClient::GetRemotePermissionUsedRecords(const PermissionUse
}
#endif
#ifdef PRIVACY_BUNDLE_START_STOP_ENABLE
void PrivacyManagerClient::ReStartUsingBundle()
{
auto proxy = GetProxy();
if (proxy == nullptr) {
LOGE(PRI_DOMAIN, PRI_TAG, "Proxy is null.");
return;
}
auto anonyStub = GetAnonyStub();
if (anonyStub == nullptr) {
LOGE(PRI_DOMAIN, PRI_TAG, "Proxy death recipent is null.");
return;
}
std::lock_guard<std::mutex> lock(startUsingBundlePermInputMutex_);
LOGI(PRI_DOMAIN, PRI_TAG, "Bundle cache size=%{public}zu.", bundleCacheList_.size());
for (const auto& info : bundleCacheList_) {
int32_t ret = proxy->StartUsingPermission(
info.bundleName, info.permissionName, anonyStub->AsObject());
ret = ConvertResult(ret);
LOGI(PRI_DOMAIN, PRI_TAG, "Recover bundle start ret=%{public}d.", ret);
}
}
void PrivacyManagerClient::SetBundleInputCache(const std::string& bundleName, const std::string& permissionName)
{
std::lock_guard<std::mutex> lock(startUsingBundlePermInputMutex_);
for (const auto& info : bundleCacheList_) {
if ((info.bundleName == bundleName) && (info.permissionName == permissionName)) {
LOGE(PRI_DOMAIN, PRI_TAG, "It already exists in bundle cache.");
return;
}
}
bundleCacheList_.emplace_back(StartUsingBundlePermInputInfo { bundleName, permissionName });
}
void PrivacyManagerClient::DeleteBundleInputCache(const std::string& bundleName, const std::string& permissionName)
{
std::lock_guard<std::mutex> lock(startUsingBundlePermInputMutex_);
for (auto it = bundleCacheList_.begin(); it != bundleCacheList_.end(); ++it) {
if ((it->bundleName == bundleName) && (it->permissionName == permissionName)) {
bundleCacheList_.erase(it);
return;
}
}
}
int32_t PrivacyManagerClient::StartUsingPermission(const std::string& bundleName, const std::string& permissionName)
{
auto proxy = GetProxy();
if (proxy == nullptr) {
LOGE(PRI_DOMAIN, PRI_TAG, "Proxy is null.");
return PrivacyError::ERR_SERVICE_ABNORMAL;
}
auto anonyStub = GetAnonyStub();
if (anonyStub == nullptr) {
LOGE(PRI_DOMAIN, PRI_TAG, "Proxy death recipent is null.");
return PrivacyError::ERR_MALLOC_FAILED;
}
int32_t ret = proxy->StartUsingPermission(bundleName, permissionName, anonyStub->AsObject());
ret = ConvertResult(ret);
LOGI(PRI_DOMAIN, PRI_TAG, "Bundle start ret=%{public}d.", ret);
if (ret == RET_SUCCESS) {
SetBundleInputCache(bundleName, permissionName);
}
return ret;
}
int32_t PrivacyManagerClient::StopUsingPermission(const std::string& bundleName, const std::string& permissionName)
{
DeleteBundleInputCache(bundleName, permissionName);
auto proxy = GetProxy();
if (proxy == nullptr) {
LOGE(PRI_DOMAIN, PRI_TAG, "Proxy is null.");
return PrivacyError::ERR_SERVICE_ABNORMAL;
}
int32_t ret = proxy->StopUsingPermission(bundleName, permissionName);
ret = ConvertResult(ret);
LOGI(PRI_DOMAIN, PRI_TAG, "Bundle stop ret=%{public}d.", ret);
return ret;
}
#endif
int32_t PrivacyManagerClient::RemovePermissionUsedRecords(AccessTokenID tokenID)
{
auto proxy = GetProxy();
@@ -567,7 +656,7 @@ int32_t PrivacyManagerClient::CreateActiveStatusChangeCbk(
}
int32_t PrivacyManagerClient::RegisterPermActiveStatusCallback(
const std::shared_ptr<PermActiveStatusCustomizedCbk>& callback)
const std::shared_ptr<PermActiveStatusCustomizedCbk>& callback, CallbackRegisterType type)
{
if (callback == nullptr) {
LOGE(PRI_DOMAIN, PRI_TAG, "CustomizedCb is nullptr.");
@@ -592,7 +681,7 @@ int32_t PrivacyManagerClient::RegisterPermActiveStatusCallback(
return PrivacyError::ERR_PARAM_INVALID;
}
result = proxy->RegisterPermActiveStatusCallback(permList, callbackWrap->AsObject());
result = proxy->RegisterPermActiveStatusCallback(permList, callbackWrap->AsObject(), static_cast<int32_t>(type));
if (result == RET_SUCCESS) {
std::lock_guard<std::mutex> lock(activeCbkMutex_);
activeCbkMap_[callback] = callbackWrap;
@@ -27,6 +27,7 @@
#include "perm_active_status_customized_cbk.h"
#include "perm_disable_policy_change_callback.h"
#include "privacy_death_recipient.h"
#include "privacy_param.h"
#include "proxy_death_callback.h"
#ifdef REMOTE_PRIVACY_ENABLE
#include "remote_caller_info.h"
@@ -43,6 +44,14 @@ struct StartUsingPermInputInfo {
PermissionUsedTypeInfo input;
bool hasCbk;
};
#ifdef PRIVACY_BUNDLE_START_STOP_ENABLE
struct StartUsingBundlePermInputInfo {
std::string bundleName;
std::string permissionName;
};
#endif
class PrivacyManagerClient final {
public:
static PrivacyManagerClient& GetInstance();
@@ -66,12 +75,18 @@ public:
int32_t successCount, int32_t failCount, bool asyncMode = false);
int32_t GetRemotePermissionUsedRecords(const PermissionUsedRequest& request, PermissionUsedResult& result);
void ReStartRemoteUsing();
#endif
#ifdef PRIVACY_BUNDLE_START_STOP_ENABLE
int32_t StartUsingPermission(const std::string& bundleName, const std::string& permissionName);
int32_t StopUsingPermission(const std::string& bundleName, const std::string& permissionName);
void ReStartUsingBundle();
#endif
int32_t RemovePermissionUsedRecords(AccessTokenID tokenID);
int32_t GetPermissionUsedRecords(const PermissionUsedRequest& request, PermissionUsedResult& result);
int32_t GetPermissionUsedRecords(
const PermissionUsedRequest& request, const sptr<OnPermissionUsedRecordCallback>& callback);
int32_t RegisterPermActiveStatusCallback(const std::shared_ptr<PermActiveStatusCustomizedCbk>& callback);
int32_t RegisterPermActiveStatusCallback(
const std::shared_ptr<PermActiveStatusCustomizedCbk>& callback, CallbackRegisterType type);
int32_t UnRegisterPermActiveStatusCallback(const std::shared_ptr<PermActiveStatusCustomizedCbk>& callback);
int32_t CreateActiveStatusChangeCbk(
const std::shared_ptr<PermActiveStatusCustomizedCbk>& callback,
@@ -113,6 +128,10 @@ private:
void SetRemoteInputCache(const RemotePermissionUsedInfo& info);
void DeleteRemoteInputCache(const RemoteCallerInfo& info, const std::string& permissionName);
#endif
#ifdef PRIVACY_BUNDLE_START_STOP_ENABLE
void SetBundleInputCache(const std::string& bundleName, const std::string& permissionName);
void DeleteBundleInputCache(const std::string& bundleName, const std::string& permissionName);
#endif
private:
std::mutex activeCbkMutex_;
@@ -130,6 +149,10 @@ private:
std::mutex startRemoteUsingPermInputMutex_;
std::vector<RemotePermissionUsedInfo> remoteCacheList_;
#endif
#ifdef PRIVACY_BUNDLE_START_STOP_ENABLE
std::mutex startUsingBundlePermInputMutex_;
std::vector<StartUsingBundlePermInputInfo> bundleCacheList_;
#endif
};
} // namespace AccessToken
} // namespace Security
@@ -44,6 +44,10 @@ ohos_unittest("libprivacy_sdk_test") {
"unittest/src/privacy_test_common.cpp",
]
if (privacy_bundle_start_stop_enable) {
sources += [ "unittest/src/privacy_bundle_using_test.cpp" ]
}
cflags_cc = access_token_cflags_cc
configs = [ "${access_token_path}/config:coverage_flags" ]
@@ -63,6 +63,24 @@ HWTEST_F(PrivacyKitTest, AddPermissionUsedRecord001, TestSize.Level0)
ASSERT_EQ(PrivacyError::ERR_SERVICE_ABNORMAL, ret);
}
/**
* @tc.name: AddPermissionUsedRecord002
* @tc.desc: AddPermissionUsedRecord with AddPermParamInfo and proxy is null.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(PrivacyKitTest, AddPermissionUsedRecord002, TestSize.Level0)
{
AddPermParamInfo info;
info.tokenId = 0xff;
info.permissionName = "ohos.permission.CAMERA";
info.successCount = 1;
info.failCount = 0;
int32_t ret = PrivacyKit::AddPermissionUsedRecord(info);
ASSERT_EQ(PrivacyError::ERR_SERVICE_ABNORMAL, ret);
}
#ifdef REMOTE_PRIVACY_ENABLE
/**
* @tc.name: AddRemotePermissionUsedRecord001
@@ -170,6 +188,22 @@ HWTEST_F(PrivacyKitTest, StartUsingPermission002, TestSize.Level0)
PrivacyKit::StartUsingPermission(g_TokenId_A, permissionName, callbackPtr));
}
#ifdef PRIVACY_BUNDLE_START_STOP_ENABLE
/**
* @tc.name: BundleUsingProxyTest001
* @tc.desc: Bundle start/stop using permission with proxy is null.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(PrivacyKitTest, BundleUsingProxyTest001, TestSize.Level0)
{
std::string bundleName = "ohos.test.bundle";
std::string permissionName = "ohos.permission.CAMERA";
ASSERT_EQ(PrivacyError::ERR_SERVICE_ABNORMAL, PrivacyKit::StartUsingPermission(bundleName, permissionName));
ASSERT_EQ(PrivacyError::ERR_SERVICE_ABNORMAL, PrivacyKit::StopUsingPermission(bundleName, permissionName));
}
#endif
/**
* @tc.name: StopUsingPermission001
* @tc.desc: StopUsingPermission proxy is null.
@@ -416,6 +450,19 @@ HWTEST_F(PrivacyKitTest, GetCurrUsingPermInfo001, TestSize.Level0)
std::vector<CurrUsingPermInfo> results;
EXPECT_EQ(PrivacyError::ERR_SERVICE_ABNORMAL, PrivacyKit::GetCurrUsingPermInfo(results));
}
/**
* @tc.name: CheckPermissionInUse001
* @tc.desc: CheckPermissionInUse proxy is null.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(PrivacyKitTest, CheckPermissionInUse001, TestSize.Level0)
{
bool isUsing = true;
EXPECT_EQ(PrivacyError::ERR_SERVICE_ABNORMAL,
PrivacyKit::CheckPermissionInUse("ohos.permission.CAMERA", isUsing));
}
} // namespace AccessToken
} // namespace Security
} // namespace OHOS
@@ -0,0 +1,767 @@
/*
* Copyright (c) 2026 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 "privacy_bundle_using_test.h"
#include <cstring>
#include <unistd.h>
#include "parameter.h"
#include "privacy_error.h"
#include "privacy_kit.h"
#include "privacy_test_common.h"
using namespace testing::ext;
namespace OHOS {
namespace Security {
namespace AccessToken {
namespace {
constexpr int32_t VALUE_MAX_LEN = 32;
uint64_t g_selfTokenId = 0;
constexpr const char* PERMISSION_USED_STATS = "ohos.permission.PERMISSION_USED_STATS";
constexpr const char* TEST_BUNDLE_NAME = "ohos.test.bundle";
constexpr const char* TEST_PERMISSION_NAME = "ohos.permission.CAMERA";
constexpr const char* EDM_CAMERA_MUTE_KEY = "persist.edm.camera_disable";
constexpr size_t INVALID_NAME_LENGTH = 257;
AccessTokenID CreateGrantedHapToken(const std::string& bundleName, const std::string& permissionName)
{
HapInfoParams infoParams = {
.userID = 0,
.bundleName = bundleName,
.instIndex = 0,
.appIDDesc = "AccessTokenBundleUsingTestAppID",
.apiVersion = PrivacyTestCommon::DEFAULT_API_VERSION,
.isSystemApp = true,
.appDistributionType = "",
};
HapPolicyParams policyParams = {
.apl = APL_NORMAL,
.domain = "accesstoken_test_domain",
};
PermissionDef permDefResult;
if (AccessTokenKit::GetDefPermission(permissionName, permDefResult) == RET_SUCCESS) {
PermissionStateFull permState = {
.permissionName = permissionName,
.isGeneral = true,
.resDeviceID = {"local_test_device"},
.grantStatus = {PermissionState::PERMISSION_GRANTED},
.grantFlags = {PermissionFlag::PERMISSION_SYSTEM_FIXED}
};
policyParams.permStateList.emplace_back(permState);
if (permDefResult.availableLevel > policyParams.apl) {
policyParams.aclRequestedList.emplace_back(permissionName);
}
}
AccessTokenIDEx tokenIdEx = PrivacyTestCommon::AllocTestHapToken(infoParams, policyParams);
return tokenIdEx.tokenIdExStruct.tokenID;
}
const CurrUsingPermInfo* FindUsingInfo(
const std::vector<CurrUsingPermInfo>& infoList, AccessTokenID tokenID, const std::string& permissionName)
{
for (const auto& info : infoList) {
if ((info.tokenID == tokenID) && (info.permissionName == permissionName)) {
return &info;
}
}
return nullptr;
}
const CurrUsingPermInfo* FindBundleUsingInfo(
const std::vector<CurrUsingPermInfo>& infoList, const std::string& bundleName, const std::string& permissionName)
{
for (const auto& info : infoList) {
if ((info.bundleName == bundleName) && (info.permissionName == permissionName)) {
return &info;
}
}
return nullptr;
}
const CurrUsingPermInfo* FindRemoteUsingInfo(const std::vector<CurrUsingPermInfo>& infoList,
const std::string& deviceId, const std::string& permissionName)
{
for (const auto& info : infoList) {
if (info.isRemote && (info.deviceId == deviceId) && (info.permissionName == permissionName)) {
return &info;
}
}
return nullptr;
}
int32_t SetDisablePolicyAsEdm(const std::string& permissionName, bool isDisable)
{
MockNativeToken mock("edm");
return PrivacyKit::SetDisablePolicy(permissionName, isDisable);
}
class BundleActiveStatusCallbackTest : public PermActiveStatusCustomizedCbk {
public:
explicit BundleActiveStatusCallbackTest(const std::vector<std::string>& permList)
: PermActiveStatusCustomizedCbk(permList)
{}
~BundleActiveStatusCallbackTest() override = default;
void ActiveStatusChangeCallback(ActiveChangeResponse& result) override
{
callTimes_++;
type_ = result.type;
callingTokenID_ = result.callingTokenID;
tokenID_ = result.tokenID;
permissionName_ = result.permissionName;
bundleName_ = result.bundleName;
}
int32_t callTimes_ = 0;
ActiveChangeType type_ = PERM_INACTIVE;
AccessTokenID callingTokenID_ = INVALID_TOKENID;
AccessTokenID tokenID_ = INVALID_TOKENID;
std::string permissionName_;
std::string bundleName_;
};
}
void BundleUsingTest::SetUpTestCase()
{
g_selfTokenId = GetSelfTokenID();
PrivacyTestCommon::SetTestEvironment(g_selfTokenId);
}
void BundleUsingTest::TearDownTestCase()
{
SetSelfTokenID(g_selfTokenId);
PrivacyTestCommon::ResetTestEvironment();
}
void BundleUsingTest::SetUp() {}
void BundleUsingTest::TearDown()
{
(void)PrivacyKit::StopUsingPermission(TEST_BUNDLE_NAME, TEST_PERMISSION_NAME);
}
/**
* @tc.name: BundleUsingtest001
* @tc.desc: Verify bundle using interfaces with invalid parameters.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(BundleUsingTest, BundleUsingtest001, TestSize.Level1)
{
std::string longBundle(INVALID_NAME_LENGTH, 'a');
std::string longPerm(INVALID_NAME_LENGTH, 'a');
EXPECT_EQ(ERR_PARAM_INVALID, PrivacyKit::StartUsingPermission("", TEST_PERMISSION_NAME));
EXPECT_EQ(ERR_PARAM_INVALID, PrivacyKit::StartUsingPermission(longBundle, TEST_PERMISSION_NAME));
EXPECT_EQ(ERR_PARAM_INVALID, PrivacyKit::StartUsingPermission(TEST_BUNDLE_NAME, ""));
EXPECT_EQ(ERR_PARAM_INVALID, PrivacyKit::StartUsingPermission(TEST_BUNDLE_NAME, longPerm));
EXPECT_EQ(ERR_PARAM_INVALID, PrivacyKit::StopUsingPermission("", TEST_PERMISSION_NAME));
EXPECT_EQ(ERR_PARAM_INVALID, PrivacyKit::StopUsingPermission(longBundle, TEST_PERMISSION_NAME));
EXPECT_EQ(ERR_PARAM_INVALID, PrivacyKit::StopUsingPermission(TEST_BUNDLE_NAME, ""));
EXPECT_EQ(ERR_PARAM_INVALID, PrivacyKit::StopUsingPermission(TEST_BUNDLE_NAME, longPerm));
}
/**
* @tc.name: BundleUsingtest002
* @tc.desc: Verify bundle start and stop succeed for system app with permission.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(BundleUsingTest, BundleUsingtest002, TestSize.Level1)
{
std::vector<std::string> reqPerm = {PERMISSION_USED_STATS};
MockHapToken mock("BundleUsingtest002", reqPerm, true);
EXPECT_EQ(RET_SUCCESS, PrivacyKit::StartUsingPermission(TEST_BUNDLE_NAME, TEST_PERMISSION_NAME));
EXPECT_EQ(RET_SUCCESS, PrivacyKit::StopUsingPermission(TEST_BUNDLE_NAME, TEST_PERMISSION_NAME));
}
/**
* @tc.name: BundleUsingtest003
* @tc.desc: Verify bundle start and stop are rejected for non-system app.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(BundleUsingTest, BundleUsingtest003, TestSize.Level1)
{
std::vector<std::string> reqPerm = {PERMISSION_USED_STATS};
MockHapToken mock("BundleUsingtest003", reqPerm, false);
EXPECT_EQ(ERR_NOT_SYSTEM_APP, PrivacyKit::StartUsingPermission(TEST_BUNDLE_NAME, TEST_PERMISSION_NAME));
EXPECT_EQ(ERR_NOT_SYSTEM_APP, PrivacyKit::StopUsingPermission(TEST_BUNDLE_NAME, TEST_PERMISSION_NAME));
}
/**
* @tc.name: BundleUsingtest004
* @tc.desc: Verify bundle start and stop are denied without permission.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(BundleUsingTest, BundleUsingtest004, TestSize.Level1)
{
std::vector<std::string> reqPerm;
MockHapToken mock("BundleUsingtest004", reqPerm, true);
EXPECT_EQ(ERR_PERMISSION_DENIED, PrivacyKit::StartUsingPermission(TEST_BUNDLE_NAME, TEST_PERMISSION_NAME));
EXPECT_EQ(ERR_PERMISSION_DENIED, PrivacyKit::StopUsingPermission(TEST_BUNDLE_NAME, TEST_PERMISSION_NAME));
}
/**
* @tc.name: BundleUsingtest005
* @tc.desc: Verify bundle repeat start and repeat stop return expected errors.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(BundleUsingTest, BundleUsingtest005, TestSize.Level1)
{
std::vector<std::string> reqPerm = {PERMISSION_USED_STATS};
MockHapToken mock("BundleUsingtest005", reqPerm, true);
EXPECT_EQ(RET_SUCCESS, PrivacyKit::StartUsingPermission(TEST_BUNDLE_NAME, TEST_PERMISSION_NAME));
EXPECT_EQ(ERR_PERMISSION_ALREADY_START_USING,
PrivacyKit::StartUsingPermission(TEST_BUNDLE_NAME, TEST_PERMISSION_NAME));
EXPECT_EQ(RET_SUCCESS, PrivacyKit::StopUsingPermission(TEST_BUNDLE_NAME, TEST_PERMISSION_NAME));
EXPECT_EQ(ERR_PERMISSION_NOT_START_USING,
PrivacyKit::StopUsingPermission(TEST_BUNDLE_NAME, TEST_PERMISSION_NAME));
}
/**
* @tc.name: BundleUsingtest006
* @tc.desc: Verify bundle start and stop return permission not exist for unsupported permission name.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(BundleUsingTest, BundleUsingtest006, TestSize.Level1)
{
std::vector<std::string> reqPerm = {PERMISSION_USED_STATS};
MockHapToken mock("BundleUsingtest006", reqPerm, true);
const std::string noexistPerm = "ohos.permission.TEST";
EXPECT_EQ(ERR_PERMISSION_NOT_EXIST, PrivacyKit::StartUsingPermission(TEST_BUNDLE_NAME, noexistPerm));
EXPECT_EQ(ERR_PERMISSION_NOT_EXIST, PrivacyKit::StopUsingPermission(TEST_BUNDLE_NAME, noexistPerm));
}
/**
* @tc.name: BundleUsingtest007
* @tc.desc: Verify bundle callback is not triggered by mute and restart is blocked by EDM policy after stop.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(BundleUsingTest, BundleUsingtest007, TestSize.Level1)
{
char value[VALUE_MAX_LEN] = {0};
GetParameter(EDM_CAMERA_MUTE_KEY, "", value, VALUE_MAX_LEN - 1);
std::string muteState(value);
std::vector<std::string> reqPerm = {PERMISSION_USED_STATS};
MockHapToken mock("BundleUsingtest007", reqPerm, true);
std::vector<std::string> permList = {TEST_PERMISSION_NAME};
auto callbackPtr = std::make_shared<BundleActiveStatusCallbackTest>(permList);
const std::string bundleName = "ohos.test.bundle.callback.mute";
AccessTokenID callingTokenID = static_cast<AccessTokenID>(GetSelfTokenID());
ASSERT_EQ(RET_SUCCESS, PrivacyKit::RegisterPermActiveStatusCallback(callbackPtr, CallbackRegisterType::ALL));
ASSERT_EQ(RET_SUCCESS, PrivacyKit::StartUsingPermission(bundleName, TEST_PERMISSION_NAME));
usleep(1000000); // 1000000: 1s
EXPECT_EQ(1, callbackPtr->callTimes_);
EXPECT_EQ(PERM_ACTIVE_IN_FOREGROUND, callbackPtr->type_);
EXPECT_EQ(callingTokenID, callbackPtr->callingTokenID_);
EXPECT_EQ(std::string(TEST_PERMISSION_NAME), callbackPtr->permissionName_);
EXPECT_EQ(bundleName, callbackPtr->bundleName_);
ASSERT_EQ(0, SetParameter(EDM_CAMERA_MUTE_KEY, "true"));
usleep(1000000); // 1000000: 1s
EXPECT_EQ(1, callbackPtr->callTimes_);
EXPECT_EQ(RET_SUCCESS, PrivacyKit::StopUsingPermission(bundleName, TEST_PERMISSION_NAME));
usleep(1000000); // 1000000: 1s
EXPECT_EQ(2, callbackPtr->callTimes_);
EXPECT_EQ(PERM_INACTIVE, callbackPtr->type_);
EXPECT_EQ(callingTokenID, callbackPtr->callingTokenID_);
EXPECT_EQ(std::string(TEST_PERMISSION_NAME), callbackPtr->permissionName_);
EXPECT_EQ(bundleName, callbackPtr->bundleName_);
EXPECT_EQ(ERR_EDM_POLICY_CHECK_FAILED, PrivacyKit::StartUsingPermission(bundleName, TEST_PERMISSION_NAME));
usleep(1000000); // 1000000: 1s
EXPECT_EQ(2, callbackPtr->callTimes_);
EXPECT_EQ(RET_SUCCESS, PrivacyKit::UnRegisterPermActiveStatusCallback(callbackPtr));
EXPECT_EQ(0, SetParameter(EDM_CAMERA_MUTE_KEY, muteState.c_str()));
}
/**
* @tc.name: BundleUsingtest008
* @tc.desc: Verify bundle callback is not triggered by disable policy and restart is blocked after stop.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(BundleUsingTest, BundleUsingtest008, TestSize.Level1)
{
bool disableBackup = false;
{
MockNativeToken mock("accesstoken_service");
ASSERT_EQ(RET_SUCCESS, PrivacyKit::GetDisablePolicy(TEST_PERMISSION_NAME, disableBackup));
}
std::vector<std::string> reqPerm = {PERMISSION_USED_STATS};
MockHapToken mock("BundleUsingtest008", reqPerm, true);
std::vector<std::string> permList = {TEST_PERMISSION_NAME};
auto callbackPtr = std::make_shared<BundleActiveStatusCallbackTest>(permList);
const std::string bundleName = "ohos.test.bundle.callback.disable";
AccessTokenID callingTokenID = static_cast<AccessTokenID>(GetSelfTokenID());
ASSERT_EQ(RET_SUCCESS, PrivacyKit::RegisterPermActiveStatusCallback(callbackPtr, CallbackRegisterType::ALL));
ASSERT_EQ(RET_SUCCESS, PrivacyKit::StartUsingPermission(bundleName, TEST_PERMISSION_NAME));
usleep(1000000); // 1000000: 1s
EXPECT_EQ(1, callbackPtr->callTimes_);
EXPECT_EQ(PERM_ACTIVE_IN_FOREGROUND, callbackPtr->type_);
EXPECT_EQ(callingTokenID, callbackPtr->callingTokenID_);
EXPECT_EQ(std::string(TEST_PERMISSION_NAME), callbackPtr->permissionName_);
EXPECT_EQ(bundleName, callbackPtr->bundleName_);
ASSERT_EQ(RET_SUCCESS, SetDisablePolicyAsEdm(TEST_PERMISSION_NAME, true));
usleep(1000000); // 1000000: 1s
EXPECT_EQ(1, callbackPtr->callTimes_);
EXPECT_EQ(RET_SUCCESS, PrivacyKit::StopUsingPermission(bundleName, TEST_PERMISSION_NAME));
usleep(1000000); // 1000000: 1s
EXPECT_EQ(2, callbackPtr->callTimes_);
EXPECT_EQ(PERM_INACTIVE, callbackPtr->type_);
EXPECT_EQ(callingTokenID, callbackPtr->callingTokenID_);
EXPECT_EQ(std::string(TEST_PERMISSION_NAME), callbackPtr->permissionName_);
EXPECT_EQ(bundleName, callbackPtr->bundleName_);
EXPECT_EQ(ERR_EDM_POLICY_CHECK_FAILED, PrivacyKit::StartUsingPermission(bundleName, TEST_PERMISSION_NAME));
usleep(1000000); // 1000000: 1s
EXPECT_EQ(2, callbackPtr->callTimes_);
EXPECT_EQ(RET_SUCCESS, PrivacyKit::UnRegisterPermActiveStatusCallback(callbackPtr));
ASSERT_EQ(RET_SUCCESS, SetDisablePolicyAsEdm(TEST_PERMISSION_NAME, disableBackup));
}
/**
* @tc.name: BundleUsingtest009
* @tc.desc: Verify GetCurrUsingPermInfo does not return bundle records when nothing is started.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(BundleUsingTest, BundleUsingtest009, TestSize.Level1)
{
std::vector<std::string> reqPerm = {PERMISSION_USED_STATS};
MockHapToken mock("BundleUsingtest009", reqPerm, true);
std::vector<CurrUsingPermInfo> infoList;
{
MockNativeToken mockQuery("audio_server");
EXPECT_EQ(RET_SUCCESS, PrivacyKit::GetCurrUsingPermInfo(infoList));
}
EXPECT_EQ(nullptr, FindBundleUsingInfo(infoList, TEST_BUNDLE_NAME, TEST_PERMISSION_NAME));
}
/**
* @tc.name: BundleUsingtest010
* @tc.desc: Verify bundle only start/stop affects GetCurrUsingPermInfo and CheckPermissionInUse.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(BundleUsingTest, BundleUsingtest010, TestSize.Level1)
{
std::vector<std::string> reqPerm = {PERMISSION_USED_STATS};
MockHapToken mock("BundleUsingtest010", reqPerm, true);
const std::string bundleName = "ohos.test.bundle.query";
EXPECT_EQ(RET_SUCCESS, PrivacyKit::StartUsingPermission(bundleName, TEST_PERMISSION_NAME));
std::vector<CurrUsingPermInfo> infoList;
{
MockNativeToken mockQuery("audio_server");
EXPECT_EQ(RET_SUCCESS, PrivacyKit::GetCurrUsingPermInfo(infoList));
}
const CurrUsingPermInfo* info = FindBundleUsingInfo(infoList, bundleName, TEST_PERMISSION_NAME);
ASSERT_NE(nullptr, info);
EXPECT_EQ(std::string(TEST_PERMISSION_NAME), info->permissionName);
EXPECT_EQ(bundleName, info->bundleName);
bool isUsing = false;
EXPECT_EQ(RET_SUCCESS, PrivacyKit::CheckPermissionInUse(TEST_PERMISSION_NAME, isUsing));
EXPECT_TRUE(isUsing);
EXPECT_EQ(RET_SUCCESS, PrivacyKit::StopUsingPermission(bundleName, TEST_PERMISSION_NAME));
infoList.clear();
{
MockNativeToken mockQuery("audio_server");
EXPECT_EQ(RET_SUCCESS, PrivacyKit::GetCurrUsingPermInfo(infoList));
}
EXPECT_EQ(nullptr, FindBundleUsingInfo(infoList, bundleName, TEST_PERMISSION_NAME));
EXPECT_EQ(RET_SUCCESS, PrivacyKit::CheckPermissionInUse(TEST_PERMISSION_NAME, isUsing));
EXPECT_FALSE(isUsing);
}
/**
* @tc.name: BundleUsingtest011
* @tc.desc: Verify CheckPermissionInUse with token only start and stop.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(BundleUsingTest, BundleUsingtest011, TestSize.Level1)
{
std::vector<std::string> reqPerm = {PERMISSION_USED_STATS};
MockHapToken mock("BundleUsingtest011", reqPerm, true);
AccessTokenID tokenID = CreateGrantedHapToken("ohos.test.bundle.token.only", TEST_PERMISSION_NAME);
ASSERT_NE(INVALID_TOKENID, tokenID);
EXPECT_EQ(RET_SUCCESS, PrivacyKit::StartUsingPermission(tokenID, TEST_PERMISSION_NAME));
bool isUsing = false;
EXPECT_EQ(RET_SUCCESS, PrivacyKit::CheckPermissionInUse(TEST_PERMISSION_NAME, isUsing));
EXPECT_TRUE(isUsing);
EXPECT_EQ(RET_SUCCESS, PrivacyKit::StopUsingPermission(tokenID, TEST_PERMISSION_NAME));
EXPECT_EQ(RET_SUCCESS, PrivacyKit::CheckPermissionInUse(TEST_PERMISSION_NAME, isUsing));
EXPECT_FALSE(isUsing);
EXPECT_EQ(RET_SUCCESS, PrivacyTestCommon::DeleteTestHapToken(tokenID));
}
/**
* @tc.name: BundleUsingtest012
* @tc.desc: Verify bundle and token together affect GetCurrUsingPermInfo and CheckPermissionInUse.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(BundleUsingTest, BundleUsingtest012, TestSize.Level1)
{
std::vector<std::string> reqPerm = {PERMISSION_USED_STATS};
MockHapToken mock("BundleUsingtest012", reqPerm, true);
AccessTokenID callingTokenID = static_cast<AccessTokenID>(GetSelfTokenID());
AccessTokenID tokenID = CreateGrantedHapToken("ohos.test.bundle.token", TEST_PERMISSION_NAME);
ASSERT_NE(INVALID_TOKENID, tokenID);
EXPECT_EQ(RET_SUCCESS, PrivacyKit::StartUsingPermission("ohos.test.bundle.mixed", TEST_PERMISSION_NAME));
EXPECT_EQ(RET_SUCCESS, PrivacyKit::StartUsingPermission(tokenID, TEST_PERMISSION_NAME));
std::vector<CurrUsingPermInfo> infoList;
{
MockNativeToken mockQuery("audio_server");
EXPECT_EQ(RET_SUCCESS, PrivacyKit::GetCurrUsingPermInfo(infoList));
}
const CurrUsingPermInfo* bundleInfo = FindBundleUsingInfo(
infoList, "ohos.test.bundle.mixed", TEST_PERMISSION_NAME);
ASSERT_NE(nullptr, bundleInfo);
EXPECT_EQ(std::string(TEST_PERMISSION_NAME), bundleInfo->permissionName);
EXPECT_EQ("ohos.test.bundle.mixed", bundleInfo->bundleName);
EXPECT_EQ(PERM_ACTIVE_IN_FOREGROUND, bundleInfo->type);
const CurrUsingPermInfo* info = FindUsingInfo(infoList, tokenID, TEST_PERMISSION_NAME);
EXPECT_NE(nullptr, info);
if (info != nullptr) {
EXPECT_EQ(callingTokenID, info->callingTokenID);
EXPECT_EQ(tokenID, info->tokenID);
EXPECT_EQ(std::string(TEST_PERMISSION_NAME), info->permissionName);
EXPECT_EQ(-1, info->pid); // -1: bundle start does not carry pid
EXPECT_EQ("", info->deviceId);
EXPECT_EQ(NORMAL_TYPE, info->usedType);
EXPECT_FALSE(info->isRemote);
}
bool isUsing = false;
EXPECT_EQ(RET_SUCCESS, PrivacyKit::CheckPermissionInUse(TEST_PERMISSION_NAME, isUsing));
EXPECT_TRUE(isUsing);
EXPECT_EQ(RET_SUCCESS, PrivacyKit::StopUsingPermission(tokenID, TEST_PERMISSION_NAME));
EXPECT_EQ(RET_SUCCESS, PrivacyKit::CheckPermissionInUse(TEST_PERMISSION_NAME, isUsing));
EXPECT_TRUE(isUsing);
EXPECT_EQ(RET_SUCCESS, PrivacyKit::StopUsingPermission("ohos.test.bundle.mixed", TEST_PERMISSION_NAME));
EXPECT_EQ(RET_SUCCESS, PrivacyKit::CheckPermissionInUse(TEST_PERMISSION_NAME, isUsing));
EXPECT_FALSE(isUsing);
EXPECT_EQ(RET_SUCCESS, PrivacyTestCommon::DeleteTestHapToken(tokenID));
}
#ifdef REMOTE_PRIVACY_ENABLE
/**
* @tc.name: BundleUsingtest013
* @tc.desc: Verify bundle, token and remote together affect GetCurrUsingPermInfo and CheckPermissionInUse.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(BundleUsingTest, BundleUsingtest013, TestSize.Level1)
{
std::vector<std::string> reqPerm = {PERMISSION_USED_STATS};
MockHapToken mock("BundleUsingtest013", reqPerm, true);
AccessTokenID callingTokenID = static_cast<AccessTokenID>(GetSelfTokenID());
AccessTokenID tokenID = CreateGrantedHapToken("ohos.test.bundle.token.remote", TEST_PERMISSION_NAME);
ASSERT_NE(INVALID_TOKENID, tokenID);
const std::string bundleName = "ohos.test.bundle.remote.mixed";
RemoteCallerInfo remoteInfo = {"remote_device_id", "remote_device_name"};
auto startRemote = [&remoteInfo]() { MockNativeToken mockRemote("camera_service");
return PrivacyKit::StartRemoteUsingPermission(remoteInfo, TEST_PERMISSION_NAME); };
auto stopRemote = [&remoteInfo]() { MockNativeToken mockRemote("camera_service");
return PrivacyKit::StopRemoteUsingPermission(remoteInfo, TEST_PERMISSION_NAME); };
auto checkInfo = [&](const std::vector<CurrUsingPermInfo>& infoList) {
const CurrUsingPermInfo* bundleInfo = FindBundleUsingInfo(infoList, bundleName, TEST_PERMISSION_NAME);
ASSERT_NE(nullptr, bundleInfo);
EXPECT_EQ(bundleName, bundleInfo->bundleName);
const CurrUsingPermInfo* tokenInfo = FindUsingInfo(infoList, tokenID, TEST_PERMISSION_NAME);
ASSERT_NE(nullptr, tokenInfo);
EXPECT_EQ(callingTokenID, tokenInfo->callingTokenID);
const CurrUsingPermInfo* remoteUsingInfo =
FindRemoteUsingInfo(infoList, remoteInfo.remoteDeviceId, TEST_PERMISSION_NAME);
ASSERT_NE(nullptr, remoteUsingInfo);
EXPECT_TRUE(remoteUsingInfo->isRemote);
};
auto checkUsing = [](bool expected) {
bool isUsing = false;
EXPECT_EQ(RET_SUCCESS, PrivacyKit::CheckPermissionInUse(TEST_PERMISSION_NAME, isUsing));
EXPECT_EQ(expected, isUsing);
};
EXPECT_EQ(RET_SUCCESS, PrivacyKit::StartUsingPermission(bundleName, TEST_PERMISSION_NAME));
EXPECT_EQ(RET_SUCCESS, PrivacyKit::StartUsingPermission(tokenID, TEST_PERMISSION_NAME));
EXPECT_EQ(RET_SUCCESS, startRemote());
std::vector<CurrUsingPermInfo> infoList;
{ MockNativeToken mockQuery("audio_server"); EXPECT_EQ(RET_SUCCESS, PrivacyKit::GetCurrUsingPermInfo(infoList)); }
checkInfo(infoList);
checkUsing(true);
EXPECT_EQ(RET_SUCCESS, stopRemote());
checkUsing(true);
EXPECT_EQ(RET_SUCCESS, PrivacyKit::StopUsingPermission(tokenID, TEST_PERMISSION_NAME));
checkUsing(true);
EXPECT_EQ(RET_SUCCESS, PrivacyKit::StopUsingPermission(bundleName, TEST_PERMISSION_NAME));
checkUsing(false);
EXPECT_EQ(RET_SUCCESS, PrivacyTestCommon::DeleteTestHapToken(tokenID));
}
#endif
/**
* @tc.name: BundleUsingtest014
* @tc.desc: Verify register callback receives bundle start active status change.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(BundleUsingTest, BundleUsingtest014, TestSize.Level1)
{
std::vector<std::string> reqPerm = {PERMISSION_USED_STATS};
MockHapToken mock("BundleUsingtest014", reqPerm, true);
AccessTokenID callingTokenID = static_cast<AccessTokenID>(GetSelfTokenID());
std::vector<std::string> permList = {TEST_PERMISSION_NAME};
auto callbackPtr = std::make_shared<BundleActiveStatusCallbackTest>(permList);
ASSERT_EQ(RET_SUCCESS, PrivacyKit::RegisterPermActiveStatusCallback(callbackPtr, CallbackRegisterType::ALL));
EXPECT_EQ(RET_SUCCESS, PrivacyKit::StartUsingPermission("ohos.test.bundle.callback", TEST_PERMISSION_NAME));
usleep(1000000); // 1000000: 1s
EXPECT_EQ(1, callbackPtr->callTimes_);
EXPECT_EQ(PERM_ACTIVE_IN_FOREGROUND, callbackPtr->type_);
EXPECT_EQ(callingTokenID, callbackPtr->callingTokenID_);
EXPECT_EQ(std::string(TEST_PERMISSION_NAME), callbackPtr->permissionName_);
EXPECT_EQ("ohos.test.bundle.callback", callbackPtr->bundleName_);
EXPECT_EQ(RET_SUCCESS, PrivacyKit::StopUsingPermission("ohos.test.bundle.callback", TEST_PERMISSION_NAME));
EXPECT_EQ(RET_SUCCESS, PrivacyKit::UnRegisterPermActiveStatusCallback(callbackPtr));
}
/**
* @tc.name: BundleUsingtest015
* @tc.desc: Verify register callback receives bundle stop active status change.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(BundleUsingTest, BundleUsingtest015, TestSize.Level1)
{
std::vector<std::string> reqPerm = {PERMISSION_USED_STATS};
MockHapToken mock("BundleUsingtest015", reqPerm, true);
AccessTokenID callingTokenID = static_cast<AccessTokenID>(GetSelfTokenID());
std::vector<std::string> permList = {TEST_PERMISSION_NAME};
auto callbackPtr = std::make_shared<BundleActiveStatusCallbackTest>(permList);
const std::string bundleName = "ohos.test.bundle.callback.stop";
ASSERT_EQ(RET_SUCCESS, PrivacyKit::RegisterPermActiveStatusCallback(callbackPtr, CallbackRegisterType::ALL));
ASSERT_EQ(RET_SUCCESS, PrivacyKit::StartUsingPermission(bundleName, TEST_PERMISSION_NAME));
usleep(1000000); // 1000000: 1s
EXPECT_EQ(RET_SUCCESS, PrivacyKit::StopUsingPermission(bundleName, TEST_PERMISSION_NAME));
usleep(1000000); // 1000000: 1s
EXPECT_EQ(2, callbackPtr->callTimes_);
EXPECT_EQ(PERM_INACTIVE, callbackPtr->type_);
EXPECT_EQ(callingTokenID, callbackPtr->callingTokenID_);
EXPECT_EQ(std::string(TEST_PERMISSION_NAME), callbackPtr->permissionName_);
EXPECT_EQ(bundleName, callbackPtr->bundleName_);
EXPECT_EQ(RET_SUCCESS, PrivacyKit::UnRegisterPermActiveStatusCallback(callbackPtr));
}
/**
* @tc.name: BundleUsingtest016
* @tc.desc: Verify TOKEN_ONLY callback does not receive bundle start and stop active status change.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(BundleUsingTest, BundleUsingtest016, TestSize.Level1)
{
std::vector<std::string> reqPerm = {PERMISSION_USED_STATS};
MockHapToken mock("BundleUsingtest016", reqPerm, true);
std::vector<std::string> permList = {TEST_PERMISSION_NAME};
auto callbackPtr = std::make_shared<BundleActiveStatusCallbackTest>(permList);
const std::string bundleName = "ohos.test.bundle.callback.tokenonly";
ASSERT_EQ(RET_SUCCESS,
PrivacyKit::RegisterPermActiveStatusCallback(callbackPtr, CallbackRegisterType::TOKEN_ONLY));
ASSERT_EQ(RET_SUCCESS, PrivacyKit::StartUsingPermission(bundleName, TEST_PERMISSION_NAME));
usleep(1000000); // 1000000: 1s
EXPECT_EQ(0, callbackPtr->callTimes_);
ASSERT_EQ(RET_SUCCESS, PrivacyKit::StopUsingPermission(bundleName, TEST_PERMISSION_NAME));
usleep(1000000); // 1000000: 1s
EXPECT_EQ(0, callbackPtr->callTimes_);
EXPECT_EQ(RET_SUCCESS, PrivacyKit::UnRegisterPermActiveStatusCallback(callbackPtr));
}
/**
* @tc.name: BundleUsingtest017
* @tc.desc: Verify callback does not receive bundle start and stop when permission does not match.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(BundleUsingTest, BundleUsingtest017, TestSize.Level1)
{
std::vector<std::string> reqPerm = {PERMISSION_USED_STATS};
MockHapToken mock("BundleUsingtest017", reqPerm, true);
std::vector<std::string> permList = {"ohos.permission.MICROPHONE"};
auto callbackPtr = std::make_shared<BundleActiveStatusCallbackTest>(permList);
const std::string bundleName = "ohos.test.bundle.callback.mismatch";
ASSERT_EQ(RET_SUCCESS, PrivacyKit::RegisterPermActiveStatusCallback(callbackPtr, CallbackRegisterType::ALL));
ASSERT_EQ(RET_SUCCESS, PrivacyKit::StartUsingPermission(bundleName, TEST_PERMISSION_NAME));
usleep(1000000); // 1000000: 1s
EXPECT_EQ(0, callbackPtr->callTimes_);
ASSERT_EQ(RET_SUCCESS, PrivacyKit::StopUsingPermission(bundleName, TEST_PERMISSION_NAME));
usleep(1000000); // 1000000: 1s
EXPECT_EQ(0, callbackPtr->callTimes_);
EXPECT_EQ(RET_SUCCESS, PrivacyKit::UnRegisterPermActiveStatusCallback(callbackPtr));
}
/**
* @tc.name: BundleUsingtest018
* @tc.desc: Verify callback does not receive bundle start and stop after unregister.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(BundleUsingTest, BundleUsingtest018, TestSize.Level1)
{
std::vector<std::string> reqPerm = {PERMISSION_USED_STATS};
MockHapToken mock("BundleUsingtest018", reqPerm, true);
std::vector<std::string> permList = {TEST_PERMISSION_NAME};
auto callbackPtr = std::make_shared<BundleActiveStatusCallbackTest>(permList);
const std::string bundleName = "ohos.test.bundle.callback.unregister";
ASSERT_EQ(RET_SUCCESS, PrivacyKit::RegisterPermActiveStatusCallback(callbackPtr, CallbackRegisterType::ALL));
ASSERT_EQ(RET_SUCCESS, PrivacyKit::UnRegisterPermActiveStatusCallback(callbackPtr));
ASSERT_EQ(RET_SUCCESS, PrivacyKit::StartUsingPermission(bundleName, TEST_PERMISSION_NAME));
usleep(1000000); // 1000000: 1s
EXPECT_EQ(0, callbackPtr->callTimes_);
ASSERT_EQ(RET_SUCCESS, PrivacyKit::StopUsingPermission(bundleName, TEST_PERMISSION_NAME));
usleep(1000000); // 1000000: 1s
EXPECT_EQ(0, callbackPtr->callTimes_);
}
/**
* @tc.name: BundleUsingtest019
* @tc.desc: Verify callback bundleName matches the actual bundle for multiple bundles.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(BundleUsingTest, BundleUsingtest019, TestSize.Level1)
{
std::vector<std::string> reqPerm = {PERMISSION_USED_STATS};
MockHapToken mock("BundleUsingtest019", reqPerm, true);
std::vector<std::string> permList = {TEST_PERMISSION_NAME};
auto callbackPtr = std::make_shared<BundleActiveStatusCallbackTest>(permList);
const std::string bundleNameA = "ohos.test.bundle.callback.multi.a";
const std::string bundleNameB = "ohos.test.bundle.callback.multi.b";
ASSERT_EQ(RET_SUCCESS, PrivacyKit::RegisterPermActiveStatusCallback(callbackPtr, CallbackRegisterType::ALL));
ASSERT_EQ(RET_SUCCESS, PrivacyKit::StartUsingPermission(bundleNameA, TEST_PERMISSION_NAME));
usleep(1000000); // 1000000: 1s
EXPECT_EQ(1, callbackPtr->callTimes_);
EXPECT_EQ(bundleNameA, callbackPtr->bundleName_);
ASSERT_EQ(RET_SUCCESS, PrivacyKit::StartUsingPermission(bundleNameB, TEST_PERMISSION_NAME));
usleep(1000000); // 1000000: 1s
EXPECT_EQ(2, callbackPtr->callTimes_);
EXPECT_EQ(bundleNameB, callbackPtr->bundleName_);
EXPECT_EQ(RET_SUCCESS, PrivacyKit::StopUsingPermission(bundleNameA, TEST_PERMISSION_NAME));
EXPECT_EQ(RET_SUCCESS, PrivacyKit::StopUsingPermission(bundleNameB, TEST_PERMISSION_NAME));
EXPECT_EQ(RET_SUCCESS, PrivacyKit::UnRegisterPermActiveStatusCallback(callbackPtr));
}
/**
* @tc.name: BundleUsingtest020
* @tc.desc: Verify ALL callback receives both bundle start and token start active status change.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(BundleUsingTest, BundleUsingtest020, TestSize.Level1)
{
std::vector<std::string> reqPerm = {PERMISSION_USED_STATS};
MockHapToken mock("BundleUsingtest020", reqPerm, true);
std::vector<std::string> permList = {TEST_PERMISSION_NAME};
auto callbackPtr = std::make_shared<BundleActiveStatusCallbackTest>(permList);
const std::string bundleName = "ohos.test.bundle.callback.all";
AccessTokenID callingTokenID = static_cast<AccessTokenID>(GetSelfTokenID());
AccessTokenID tokenID = CreateGrantedHapToken("ohos.test.bundle.callback.token", TEST_PERMISSION_NAME);
ASSERT_NE(INVALID_TOKENID, tokenID);
ASSERT_EQ(RET_SUCCESS, PrivacyKit::RegisterPermActiveStatusCallback(callbackPtr, CallbackRegisterType::ALL));
ASSERT_EQ(RET_SUCCESS, PrivacyKit::StartUsingPermission(bundleName, TEST_PERMISSION_NAME));
usleep(1000000); // 1000000: 1s
EXPECT_EQ(1, callbackPtr->callTimes_);
EXPECT_EQ(PERM_ACTIVE_IN_FOREGROUND, callbackPtr->type_);
EXPECT_EQ(callingTokenID, callbackPtr->callingTokenID_);
EXPECT_EQ(INVALID_TOKENID, callbackPtr->tokenID_);
EXPECT_EQ(std::string(TEST_PERMISSION_NAME), callbackPtr->permissionName_);
EXPECT_EQ(bundleName, callbackPtr->bundleName_);
ASSERT_EQ(RET_SUCCESS, PrivacyKit::StartUsingPermission(tokenID, TEST_PERMISSION_NAME));
usleep(1000000); // 1000000: 1s
EXPECT_EQ(2, callbackPtr->callTimes_);
EXPECT_EQ(callingTokenID, callbackPtr->callingTokenID_);
EXPECT_EQ(tokenID, callbackPtr->tokenID_);
EXPECT_EQ(std::string(TEST_PERMISSION_NAME), callbackPtr->permissionName_);
EXPECT_EQ("", callbackPtr->bundleName_);
EXPECT_EQ(RET_SUCCESS, PrivacyKit::StopUsingPermission(tokenID, TEST_PERMISSION_NAME));
EXPECT_EQ(RET_SUCCESS, PrivacyKit::StopUsingPermission(bundleName, TEST_PERMISSION_NAME));
EXPECT_EQ(RET_SUCCESS, PrivacyKit::UnRegisterPermActiveStatusCallback(callbackPtr));
EXPECT_EQ(RET_SUCCESS, PrivacyTestCommon::DeleteTestHapToken(tokenID));
}
} // namespace AccessToken
} // namespace Security
} // namespace OHOS
@@ -0,0 +1,35 @@
/*
* Copyright (c) 2026 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 PRIVACY_BUNDLE_USING_TEST_H
#define PRIVACY_BUNDLE_USING_TEST_H
#include <gtest/gtest.h>
namespace OHOS {
namespace Security {
namespace AccessToken {
class BundleUsingTest : public testing::Test {
public:
static void SetUpTestCase();
static void TearDownTestCase();
void SetUp() override;
void TearDown() override;
};
} // namespace AccessToken
} // namespace Security
} // namespace OHOS
#endif // PRIVACY_BUNDLE_USING_TEST_H
@@ -372,3 +372,88 @@ HWTEST_F(PrivacyKitTest, OnAddPrivacySa003, TestSize.Level0)
EXPECT_EQ(PrivacyManagerClient::GetInstance().remoteCacheList_.size(), 0);
}
#endif
#ifdef PRIVACY_BUNDLE_START_STOP_ENABLE
/**
* @tc.name: SystemAbilityStatusChangeListener004
* @tc.desc:
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(PrivacyKitTest, OnAddPrivacySa004, TestSize.Level0)
{
const std::string bundleName = g_infoParmsE.bundleName;
const std::string permissionName = "ohos.permission.CAMERA";
EXPECT_EQ(0, PrivacyManagerClient::GetInstance().bundleCacheList_.size());
EXPECT_EQ(0, PrivacyKit::StartUsingPermission(bundleName, permissionName));
EXPECT_EQ(1, PrivacyManagerClient::GetInstance().bundleCacheList_.size());
EXPECT_EQ(ERR_PERMISSION_ALREADY_START_USING, PrivacyKit::StartUsingPermission(bundleName, permissionName));
EXPECT_EQ(1, PrivacyManagerClient::GetInstance().bundleCacheList_.size());
PrivacyManagerClient::GetInstance().OnAddPrivacySa();
PrivacyManagerClient::GetInstance().OnRemoteDiedHandle();
PrivacyManagerClient::GetInstance().OnAddPrivacySa();
EXPECT_EQ(0, PrivacyKit::StopUsingPermission(bundleName, permissionName));
EXPECT_EQ(0, PrivacyManagerClient::GetInstance().bundleCacheList_.size());
}
/**
* @tc.name: BundleClientCache001
* @tc.desc: Verify bundle cache is created after successful bundle start.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(PrivacyKitTest, BundleClientCache001, TestSize.Level0)
{
const std::string bundleName = g_infoParmsE.bundleName;
const std::string permissionName = "ohos.permission.CAMERA";
PrivacyManagerClient::GetInstance().bundleCacheList_.clear();
EXPECT_EQ(0, PrivacyManagerClient::GetInstance().bundleCacheList_.size());
EXPECT_EQ(0, PrivacyKit::StartUsingPermission(bundleName, permissionName));
EXPECT_EQ(1, PrivacyManagerClient::GetInstance().bundleCacheList_.size());
EXPECT_EQ(0, PrivacyKit::StopUsingPermission(bundleName, permissionName));
}
/**
* @tc.name: BundleClientCache002
* @tc.desc: Verify bundle cache is removed after bundle stop.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(PrivacyKitTest, BundleClientCache002, TestSize.Level0)
{
const std::string bundleName = g_infoParmsE.bundleName;
const std::string permissionName = "ohos.permission.CAMERA";
PrivacyManagerClient::GetInstance().bundleCacheList_.clear();
EXPECT_EQ(0, PrivacyKit::StartUsingPermission(bundleName, permissionName));
EXPECT_EQ(1, PrivacyManagerClient::GetInstance().bundleCacheList_.size());
EXPECT_EQ(0, PrivacyKit::StopUsingPermission(bundleName, permissionName));
EXPECT_EQ(0, PrivacyManagerClient::GetInstance().bundleCacheList_.size());
}
/**
* @tc.name: BundleClientRetry003
* @tc.desc: Verify OnAddPrivacySa replays bundle cache without duplicating entries.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(PrivacyKitTest, BundleClientRetry003, TestSize.Level0)
{
const std::string bundleName = g_infoParmsE.bundleName;
const std::string permissionName = "ohos.permission.CAMERA";
PrivacyManagerClient::GetInstance().bundleCacheList_.clear();
EXPECT_EQ(0, PrivacyKit::StartUsingPermission(bundleName, permissionName));
EXPECT_EQ(1, PrivacyManagerClient::GetInstance().bundleCacheList_.size());
PrivacyManagerClient::GetInstance().OnAddPrivacySa();
EXPECT_EQ(1, PrivacyManagerClient::GetInstance().bundleCacheList_.size());
EXPECT_EQ(0, PrivacyKit::StopUsingPermission(bundleName, permissionName));
EXPECT_EQ(0, PrivacyManagerClient::GetInstance().bundleCacheList_.size());
}
#endif
@@ -727,9 +727,7 @@ HWTEST_F(PrivacyKitTest, AddRemotePermissionUsedRecordTest001, TestSize.Level0)
uint32_t selfUid = getuid();
setuid(USER_100_UID);
RemoteCallerInfo info;
info.remoteDeviceId = "ididid";
info.remoteDeviceName = "namename";
RemoteCallerInfo info = {"ididid", "namename"};
std::string permissionName = "ohos.permission.CAMERA";
info.remoteDeviceId = "";
@@ -772,9 +770,7 @@ HWTEST_F(PrivacyKitTest, AddRemotePermissionUsedRecordTest002, TestSize.Level0)
uint32_t selfUid = getuid();
setuid(USER_100_UID);
RemoteCallerInfo info;
info.remoteDeviceId = "ididid";
info.remoteDeviceName = "namename";
RemoteCallerInfo info = {"ididid", "namename"};
std::string permissionName = "ohos.permission.CAMERA";
EXPECT_EQ(RET_NO_ERROR, PrivacyKit::AddRemotePermissionUsedRecord(info, permissionName, 1, 0));
@@ -817,9 +813,7 @@ HWTEST_F(PrivacyKitTest, AddRecordWithToggleFalseTest001, TestSize.Level1)
uint32_t selfUid = getuid();
setuid(USER_100_UID);
RemoteCallerInfo info;
info.remoteDeviceId = "ididid";
info.remoteDeviceName = "namename";
RemoteCallerInfo info = {"ididid", "namename"};
std::string permissionName = "ohos.permission.CAMERA";
EXPECT_EQ(RET_NO_ERROR, PrivacyKit::AddRemotePermissionUsedRecord(info, permissionName, 1, 0));
@@ -860,9 +854,7 @@ HWTEST_F(PrivacyKitTest, GetRemotePermissionUsedRecordTest001, TestSize.Level0)
uint32_t selfUid = getuid();
setuid(USER_100_UID);
RemoteCallerInfo info;
info.remoteDeviceId = "ididid";
info.remoteDeviceName = "namename";
RemoteCallerInfo info = {"ididid", "namename"};
std::string permissionName = "ohos.permission.CAMERA";
EXPECT_EQ(RET_NO_ERROR, PrivacyKit::AddRemotePermissionUsedRecord(info, permissionName, 1, 0));
@@ -908,9 +900,7 @@ HWTEST_F(PrivacyKitTest, GetRemotePermissionUsedRecordTest002, TestSize.Level0)
uint32_t selfUid = getuid();
setuid(USER_100_UID);
RemoteCallerInfo info;
info.remoteDeviceId = "ididid";
info.remoteDeviceName = "namename";
RemoteCallerInfo info = {"ididid", "namename"};
std::string permissionName = "ohos.permission.CAMERA";
EXPECT_EQ(RET_NO_ERROR, PrivacyKit::AddRemotePermissionUsedRecord(info, permissionName, 1, 0));
@@ -953,9 +943,7 @@ HWTEST_F(PrivacyKitTest, GetRemotePermissionUsedRecordTest003, TestSize.Level0)
uint32_t selfUid = getuid();
setuid(USER_100_UID);
RemoteCallerInfo info;
info.remoteDeviceId = "ididid";
info.remoteDeviceName = "namename";
RemoteCallerInfo info = {"ididid", "namename"};
std::string permissionName = "ohos.permission.CAMERA";
EXPECT_EQ(RET_NO_ERROR, PrivacyKit::AddRemotePermissionUsedRecord(info, permissionName, 1, 0));
@@ -1006,9 +994,7 @@ HWTEST_F(PrivacyKitTest, GetRemotePermissionUsedRecordTest004, TestSize.Level0)
uint32_t selfUid = getuid();
setuid(USER_100_UID);
RemoteCallerInfo info;
info.remoteDeviceId = "ididid";
info.remoteDeviceName = "namename";
RemoteCallerInfo info = {"ididid", "namename"};
std::string permissionName = "ohos.permission.CAMERA";
EXPECT_EQ(RET_NO_ERROR, PrivacyKit::AddRemotePermissionUsedRecord(info, permissionName, 1, 0));
@@ -1049,9 +1035,7 @@ HWTEST_F(PrivacyKitTest, GetRemotePermissionUsedRecordTest004, TestSize.Level0)
*/
HWTEST_F(PrivacyKitTest, StartRemoteUsingPermission001, TestSize.Level0)
{
RemoteCallerInfo info;
info.remoteDeviceId = "ididid";
info.remoteDeviceName = "namename";
RemoteCallerInfo info = {"ididid", "namename"};
info.remoteDeviceId = "";
EXPECT_EQ(PrivacyError::ERR_PARAM_INVALID, PrivacyKit::StartRemoteUsingPermission(info, "ohos.permission.CAMERA"));
@@ -1111,9 +1095,7 @@ HWTEST_F(PrivacyKitTest, StartRemoteUsingPermission002, TestSize.Level1)
auto callbackPtr = std::make_shared<CbCustomizeTest6>(permList);
EXPECT_EQ(RET_NO_ERROR, PrivacyKit::RegisterPermActiveStatusCallback(callbackPtr));
RemoteCallerInfo info;
info.remoteDeviceId = "ididid";
info.remoteDeviceName = "namename";
RemoteCallerInfo info = {"ididid", "namename"};
EXPECT_EQ(RET_NO_ERROR, PrivacyKit::StartRemoteUsingPermission(info, "ohos.permission.CAMERA"));
usleep(1000000); // 1000000us = 1s
EXPECT_EQ(callbackPtr->callTimes, 0);
@@ -1133,17 +1115,14 @@ HWTEST_F(PrivacyKitTest, StartRemoteUsingPermission002, TestSize.Level1)
*/
HWTEST_F(PrivacyKitTest, StartRemoteUsingPermission003, TestSize.Level1)
{
AccessTokenID cameraToken = PrivacyTestCommon::GetNativeTokenIdFromProcess("camera_service");
SetSelfTokenID(cameraToken);
MockNativeToken mock("camera_service");
EXPECT_EQ(RET_NO_ERROR, SetDisablePolicy("ohos.permission.MICROPHONE", false));
std::vector<std::string> permList = {"ohos.permission.CAMERA"};
auto callbackPtr = std::make_shared<CbCustomizeTest6>(permList);
EXPECT_EQ(RET_NO_ERROR, PrivacyKit::RegisterPermActiveStatusCallback(callbackPtr));
RemoteCallerInfo info;
info.remoteDeviceId = "ididid";
info.remoteDeviceName = "namename";
RemoteCallerInfo info = {"ididid", "namename"};
EXPECT_EQ(RET_NO_ERROR, PrivacyKit::StartRemoteUsingPermission(info, "ohos.permission.CAMERA"));
usleep(1000000); // 1000000us = 1s
EXPECT_EQ(callbackPtr->type_, PERM_REMOTE_USING);
@@ -1153,8 +1132,7 @@ HWTEST_F(PrivacyKitTest, StartRemoteUsingPermission003, TestSize.Level1)
EXPECT_EQ(callbackPtr->callTimes, 1);
info.remoteDeviceId = "ididid2222";
EXPECT_EQ(PrivacyError::ERR_REMOTE_USING_CONFLICT,
PrivacyKit::StartRemoteUsingPermission(info, "ohos.permission.CAMERA"));
EXPECT_EQ(ERR_REMOTE_USING_CONFLICT, PrivacyKit::StartRemoteUsingPermission(info, "ohos.permission.CAMERA"));
info.remoteDeviceId = "ididid";
usleep(1000000); // 1000000us = 1s
EXPECT_EQ(callbackPtr->callTimes, 1);
@@ -1168,8 +1146,7 @@ HWTEST_F(PrivacyKitTest, StartRemoteUsingPermission003, TestSize.Level1)
EXPECT_EQ(callbackPtr->callTimes, 2);
info.remoteDeviceId = "ididid2222";
EXPECT_EQ(PrivacyError::ERR_PERMISSION_NOT_START_USING,
PrivacyKit::StopRemoteUsingPermission(info, "ohos.permission.CAMERA"));
EXPECT_EQ(ERR_PERMISSION_NOT_START_USING, PrivacyKit::StopRemoteUsingPermission(info, "ohos.permission.CAMERA"));
usleep(1000000); // 1000000us = 1s
EXPECT_EQ(callbackPtr->callTimes, 2);
info.remoteDeviceId = "ididid";
@@ -1186,12 +1163,13 @@ HWTEST_F(PrivacyKitTest, StartRemoteUsingPermission003, TestSize.Level1)
usleep(1000000); // 1000000us = 1s
EXPECT_EQ(callbackPtr->callTimes, 4);
EXPECT_EQ(PrivacyError::ERR_PERMISSION_NOT_START_USING,
EXPECT_EQ(ERR_PERMISSION_NOT_START_USING,
PrivacyKit::StopRemoteUsingPermission(info, "ohos.permission.CAMERA"));
EXPECT_EQ(RET_NO_ERROR, PrivacyKit::UnRegisterPermActiveStatusCallback(callbackPtr));
EXPECT_EQ(RET_NO_ERROR, PrivacyKit::StopRemoteUsingPermission(info, "ohos.permission.MICROPHONE"));
EXPECT_EQ(RET_NO_ERROR, PrivacyKit::StopRemoteUsingPermission(info, "ohos.permission.MICROPHONE"));
SetSelfTokenID(g_selfTokenId);
EXPECT_EQ(RET_NO_ERROR, PrivacyKit::UnRegisterPermActiveStatusCallback(callbackPtr));
}
/**
@@ -1202,17 +1180,14 @@ HWTEST_F(PrivacyKitTest, StartRemoteUsingPermission003, TestSize.Level1)
*/
HWTEST_F(PrivacyKitTest, StartRemoteUsingPermission004, TestSize.Level1)
{
AccessTokenID cameraToken = PrivacyTestCommon::GetNativeTokenIdFromProcess("camera_service");
SetSelfTokenID(cameraToken);
MockNativeToken mock("camera_service");
EXPECT_EQ(RET_NO_ERROR, SetDisablePolicy("ohos.permission.MICROPHONE", false));
std::vector<std::string> permList;
auto callbackPtr = std::make_shared<CbCustomizeTest6>(permList);
EXPECT_EQ(RET_NO_ERROR, PrivacyKit::RegisterPermActiveStatusCallback(callbackPtr));
RemoteCallerInfo info;
info.remoteDeviceId = "ididid";
info.remoteDeviceName = "namename";
RemoteCallerInfo info = {"ididid", "namename"};
EXPECT_EQ(RET_NO_ERROR, PrivacyKit::StartRemoteUsingPermission(info, "ohos.permission.CAMERA"));
usleep(1000000); // 1000000us = 1s
EXPECT_EQ(callbackPtr->type_, PERM_REMOTE_USING);
@@ -1234,8 +1209,6 @@ HWTEST_F(PrivacyKitTest, StartRemoteUsingPermission004, TestSize.Level1)
EXPECT_EQ(callbackPtr->callTimes, 4);
EXPECT_EQ(RET_NO_ERROR, PrivacyKit::UnRegisterPermActiveStatusCallback(callbackPtr));
SetSelfTokenID(g_selfTokenId);
}
#else
/**
@@ -1246,9 +1219,7 @@ HWTEST_F(PrivacyKitTest, StartRemoteUsingPermission004, TestSize.Level1)
*/
HWTEST_F(PrivacyKitTest, RemotePrivacyLiteTest001, TestSize.Level0)
{
RemoteCallerInfo info;
info.remoteDeviceId = "ididid";
info.remoteDeviceName = "namename";
RemoteCallerInfo info = {"ididid", "namename"};
std::string permissionName = "ohos.permission.CAMERA";
EXPECT_EQ(PrivacyError::ERR_CAPABILITY_NOT_SUPPORT, PrivacyKit::StartRemoteUsingPermission(info, permissionName));
EXPECT_EQ(PrivacyError::ERR_CAPABILITY_NOT_SUPPORT, PrivacyKit::StopRemoteUsingPermission(info, permissionName));
@@ -1809,6 +1780,13 @@ HWTEST_F(PrivacyKitTest, RegisterPermActiveStatusCallback003, TestSize.Level0)
permList.emplace_back("ohos.permission.MICROPHONE");
auto callbackPtr = std::make_shared<CbCustomizeTest3>(permList);
EXPECT_EQ(PrivacyError::ERR_PARAM_INVALID, PrivacyKit::RegisterPermActiveStatusCallback(callbackPtr));
std::vector<std::string> validPermList = {"ohos.permission.CAMERA"};
auto callbackPtr2 = std::make_shared<CbCustomizeTest3>(validPermList);
EXPECT_EQ(PrivacyError::ERR_PARAM_INVALID,
PrivacyKit::RegisterPermActiveStatusCallback(callbackPtr2, static_cast<CallbackRegisterType>(-1)));
EXPECT_EQ(PrivacyError::ERR_PARAM_INVALID,
PrivacyKit::RegisterPermActiveStatusCallback(callbackPtr2, static_cast<CallbackRegisterType>(2)));
}
/**
@@ -1932,7 +1910,8 @@ HWTEST_F(PrivacyKitTest, RegisterPermActiveStatusCallback009, TestSize.Level0)
{
std::shared_ptr<PermActiveStatusCustomizedCbk> callback = nullptr;
EXPECT_EQ(nullptr, callback);
PrivacyManagerClient::GetInstance().RegisterPermActiveStatusCallback(callback); // callback is null
PrivacyManagerClient::GetInstance().RegisterPermActiveStatusCallback(
callback, CallbackRegisterType::TOKEN_ONLY); // callback is null
}
/**
@@ -2763,12 +2742,11 @@ public:
*/
HWTEST_F(PrivacyKitTest, OnRemoteRequest003, TestSize.Level0)
{
ActiveChangeResponse response = {
.tokenID = 123,
.permissionName = "ohos.permission.CAMERA",
.deviceId = "I don't know",
.type = ActiveChangeType::PERM_INACTIVE
};
ActiveChangeResponse response;
response.tokenID = 123;
response.permissionName = "ohos.permission.CAMERA";
response.deviceId = "I don't know";
response.type = ActiveChangeType::PERM_INACTIVE;
ActiveChangeResponseParcel responseParcel;
responseParcel.changeResponse = response;
@@ -2798,12 +2776,11 @@ HWTEST_F(PrivacyKitTest, OnRemoteRequest003, TestSize.Level0)
*/
HWTEST_F(PrivacyKitTest, ActiveStatusChangeCallback001, TestSize.Level0)
{
ActiveChangeResponse response = {
.tokenID = 123,
.permissionName = "ohos.permission.CAMERA",
.deviceId = "I don't know",
.type = ActiveChangeType::PERM_INACTIVE
};
ActiveChangeResponse response;
response.tokenID = 123;
response.permissionName = "ohos.permission.CAMERA";
response.deviceId = "I don't know";
response.type = ActiveChangeType::PERM_INACTIVE;
std::vector<std::string> permList = {"ohos.permission.CAMERA"};
std::shared_ptr<PermActiveStatusCustomizedCbk> callbackPtr = std::make_shared<CbCustomizeTest1>(permList);
OHOS::sptr<PermActiveStatusChangeCallback> callback = new (
@@ -3724,6 +3701,108 @@ HWTEST_F(PrivacyKitTest, SetPermissionUsedRecordToggleStatus004, TestSize.Level0
EXPECT_EQ(PrivacyError::ERR_NOT_SYSTEM_APP, PrivacyKit::GetPermissionUsedRecordToggleStatus(USER_ID_2, status));
}
#ifdef PRIVACY_BUNDLE_START_STOP_ENABLE
/**
* @tc.name: BundleUsingPermissionCacheKeyTest001
* @tc.desc: Verify bundle start keeps different permissions for the same bundle observable from kit results.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(PrivacyKitTest, BundleUsingPermissionCacheKeyTest001, TestSize.Level0)
{
std::vector<std::string> reqPerm = {"ohos.permission.PERMISSION_USED_STATS"};
MockHapToken mock("BundleUsingPermissionCacheKeyTest001", reqPerm, true);
const std::string bundleName = g_infoParmsE.bundleName;
const std::string cameraPermission = "ohos.permission.CAMERA";
const std::string microphonePermission = "ohos.permission.MICROPHONE";
auto findBundleInfo = [](const std::vector<CurrUsingPermInfo>& infoList,
const std::string& targetBundle, const std::string& targetPermission) {
for (const auto& info : infoList) {
if ((info.bundleName == targetBundle) && (info.permissionName == targetPermission)) {
return true;
}
}
return false;
};
ASSERT_EQ(RET_NO_ERROR, PrivacyKit::StartUsingPermission(bundleName, cameraPermission));
ASSERT_EQ(RET_NO_ERROR, PrivacyKit::StartUsingPermission(bundleName, microphonePermission));
MockNativeToken queryToken("audio_server");
std::vector<CurrUsingPermInfo> infoList;
ASSERT_EQ(RET_NO_ERROR, PrivacyKit::GetCurrUsingPermInfo(infoList));
EXPECT_TRUE(findBundleInfo(infoList, bundleName, cameraPermission));
EXPECT_TRUE(findBundleInfo(infoList, bundleName, microphonePermission));
ASSERT_EQ(RET_NO_ERROR, PrivacyKit::StopUsingPermission(bundleName, cameraPermission));
infoList.clear();
ASSERT_EQ(RET_NO_ERROR, PrivacyKit::GetCurrUsingPermInfo(infoList));
EXPECT_FALSE(findBundleInfo(infoList, bundleName, cameraPermission));
EXPECT_TRUE(findBundleInfo(infoList, bundleName, microphonePermission));
ASSERT_EQ(RET_NO_ERROR, PrivacyKit::StopUsingPermission(bundleName, microphonePermission));
}
/**
* @tc.name: BundleUsingPermissionCacheKeyTest002
* @tc.desc: Verify bundle start keeps different bundles for the same permission observable from kit results.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(PrivacyKitTest, BundleUsingPermissionCacheKeyTest002, TestSize.Level0)
{
std::vector<std::string> reqPerm = {"ohos.permission.PERMISSION_USED_STATS"};
MockHapToken mock("BundleUsingPermissionCacheKeyTest002", reqPerm, true);
const std::string bundleNameA = g_infoParmsE.bundleName;
const std::string bundleNameB = g_infoParmsF.bundleName;
const std::string permissionName = "ohos.permission.CAMERA";
auto findBundleInfo = [](const std::vector<CurrUsingPermInfo>& infoList,
const std::string& targetBundle, const std::string& targetPermission) {
for (const auto& info : infoList) {
if ((info.bundleName == targetBundle) && (info.permissionName == targetPermission)) {
return true;
}
}
return false;
};
ASSERT_EQ(RET_NO_ERROR, PrivacyKit::StartUsingPermission(bundleNameA, permissionName));
ASSERT_EQ(RET_NO_ERROR, PrivacyKit::StartUsingPermission(bundleNameB, permissionName));
MockNativeToken queryToken("audio_server");
std::vector<CurrUsingPermInfo> infoList;
ASSERT_EQ(RET_NO_ERROR, PrivacyKit::GetCurrUsingPermInfo(infoList));
EXPECT_TRUE(findBundleInfo(infoList, bundleNameA, permissionName));
EXPECT_TRUE(findBundleInfo(infoList, bundleNameB, permissionName));
ASSERT_EQ(RET_NO_ERROR, PrivacyKit::StopUsingPermission(bundleNameA, permissionName));
infoList.clear();
ASSERT_EQ(RET_NO_ERROR, PrivacyKit::GetCurrUsingPermInfo(infoList));
EXPECT_FALSE(findBundleInfo(infoList, bundleNameA, permissionName));
EXPECT_TRUE(findBundleInfo(infoList, bundleNameB, permissionName));
ASSERT_EQ(RET_NO_ERROR, PrivacyKit::StopUsingPermission(bundleNameB, permissionName));
}
#endif
#ifndef PRIVACY_BUNDLE_START_STOP_ENABLE
/**
* @tc.name: BundleUsingCapabilityTest001
* @tc.desc: Verify bundle start and stop return capability not support when feature is disabled.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(PrivacyKitTest, BundleUsingCapabilityTest001, TestSize.Level0)
{
EXPECT_EQ(PrivacyError::ERR_CAPABILITY_NOT_SUPPORT,
PrivacyKit::StartUsingPermission("ohos.privacy_test.bundle.unsupport", "ohos.permission.CAMERA"));
EXPECT_EQ(PrivacyError::ERR_CAPABILITY_NOT_SUPPORT,
PrivacyKit::StopUsingPermission("ohos.privacy_test.bundle.unsupport", "ohos.permission.CAMERA"));
}
#endif
int32_t PrivacyKitTest::SetDisablePolicy(const std::string& permissionName, bool isDisable)
{
MockNativeToken mock("edm");
@@ -33,7 +33,8 @@ interface OHOS.Security.AccessToken.IPrivacyManager {
[ipccode 6] void RemovePermissionUsedRecords([in] unsigned int tokenID);
[ipccode 7] void GetPermissionUsedRecords([in] PermissionUsedRequestParcel request, [out] PermissionUsedResultParcel resultParcel);
[ipccode 8] void GetPermissionUsedRecordsAsync([in] PermissionUsedRequestParcel request, [in] OnPermissionUsedRecordCallback cb);
[ipccode 9] void RegisterPermActiveStatusCallback([in] List<String> permList, [in] IRemoteObject cb);
[ipccode 9] void RegisterPermActiveStatusCallback([in] List<String> permList, [in] IRemoteObject cb,
[in] int type);
[ipccode 10] void UnRegisterPermActiveStatusCallback([in] IRemoteObject cb);
[ipccode 11] boolean IsAllowedUsingPermission([in] unsigned int tokenID, [in] String permissionName, [in] int pid);
[ipccode 12] void GetPermissionUsedTypeInfos([in] unsigned int tokenId, [in] String permissionName, [out] List<PermissionUsedTypeInfoParcel> resultsParcel);
@@ -52,4 +53,7 @@ interface OHOS.Security.AccessToken.IPrivacyManager {
[ipccode 25, macrodef REMOTE_PRIVACY_ENABLE] void AddRemotePermissionUsedRecord([in] RemoteAddPermParamInfoParcel infoParcel);
[ipccode 26, oneway, macrodef REMOTE_PRIVACY_ENABLE] void AddRemotePermissionUsedRecordAsync([in] RemoteAddPermParamInfoParcel infoParcel);
[ipccode 27, macrodef REMOTE_PRIVACY_ENABLE] void GetRemotePermissionUsedRecords([in] PermissionUsedRequestParcel request, [out] PermissionUsedResultParcel resultParcel);
[ipccode 28, macrodef PRIVACY_BUNDLE_START_STOP_ENABLE] void StartUsingPermission([in] String bundleName, [in] String permissionName,
[in] IRemoteObject anonyStub);
[ipccode 29, macrodef PRIVACY_BUNDLE_START_STOP_ENABLE] void StopUsingPermission([in] String bundleName, [in] String permissionName);
}
@@ -27,6 +27,7 @@
#include "active_change_response_info.h"
#include "perm_active_status_callback_death_recipient.h"
#include "perm_active_status_change_callback_proxy.h"
#include "privacy_param.h"
namespace OHOS {
namespace Security {
@@ -34,13 +35,15 @@ namespace AccessToken {
struct CallbackData {
CallbackData() : permList_(), callbackObject_(nullptr)
{}
CallbackData(const std::vector<std::string>& permList, sptr<IRemoteObject> callback)
: permList_(permList), callbackObject_(callback)
CallbackData(AccessTokenID tokenId, const std::vector<std::string>& permList, sptr<IRemoteObject> callback,
int32_t type)
: registerTokenId(tokenId), permList_(permList), callbackObject_(callback), registerType_(type)
{}
AccessTokenID registerTokenId {0};
std::vector<std::string> permList_;
sptr<IRemoteObject> callbackObject_;
int32_t registerType_;
};
class ActiveStatusCallbackManager {
@@ -50,11 +53,13 @@ public:
static ActiveStatusCallbackManager& GetInstance();
int32_t AddCallback(
AccessTokenID regiterTokenId, const std::vector<std::string>& permList, const sptr<IRemoteObject>& callback);
AccessTokenID regiterTokenId, const std::vector<std::string>& permList, const sptr<IRemoteObject>& callback,
int32_t registerType);
int32_t RemoveCallback(const sptr<IRemoteObject>& callback);
bool NeedCalled(const std::vector<std::string>& permList, const std::string& permName);
void ExecuteCallbackAsync(ActiveChangeResponse& info);
void ActiveStatusChange(ActiveChangeResponse& info);
bool NeedNotify(CallbackRegisterType registerType, CallbackRegisterType sourceType) const;
void ExecuteCallbackAsync(ActiveChangeResponse& info, CallbackRegisterType sourceType);
void ActiveStatusChange(ActiveChangeResponse& info, CallbackRegisterType sourceType);
private:
std::mutex mutex_;
std::vector<CallbackData> callbackDataList_;
@@ -90,7 +90,6 @@ public:
int32_t callerPid);
int32_t StopUsingPermission(AccessTokenID tokenId, int32_t pid, const std::string& permissionName,
int32_t callerPid);
bool HasCallerInStartList(int32_t callerPid);
#ifdef REMOTE_PRIVACY_ENABLE
int32_t StartRemoteUsingPermission(const RemotePermissionUsedInfo &info, int32_t callerPid);
int32_t StopRemoteUsingPermission(const std::string& remoteDeviceId, const std::string& remoteDeviceName,
@@ -100,8 +99,13 @@ public:
int32_t AddRemotePermissionUsedRecord(const RemoteAddPermParamInfo& info);
int32_t GetRemotePermissionUsedRecords(const PermissionUsedRequest& request, PermissionUsedResult& result);
#endif
int32_t RegisterPermActiveStatusCallback(
AccessTokenID regiterTokenId, const std::vector<std::string>& permList, const sptr<IRemoteObject>& callback);
#ifdef PRIVACY_BUNDLE_START_STOP_ENABLE
int32_t StartUsingPermission(const std::string& bundleName, const std::string& permissionName, int32_t callerPid);
int32_t StopUsingPermission(const std::string& bundleName, const std::string& permissionName, int32_t callerPid);
#endif
bool HasCallerInStartList(int32_t callerPid);
int32_t RegisterPermActiveStatusCallback(AccessTokenID regiterTokenId, const std::vector<std::string>& permList,
const sptr<IRemoteObject>& callback, int32_t type);
int32_t UnRegisterPermActiveStatusCallback(const sptr<IRemoteObject>& callback);
void CallbackExecute(const ContinuousPermissionRecord& record, const std::string& permissionName,
@@ -312,6 +316,10 @@ private:
std::mutex remotePermUsedRecMutex_;
std::vector<RemotePermissionRecordCache> remotePermUsedRecList_;
#endif
#ifdef PRIVACY_BUNDLE_START_STOP_ENABLE
std::mutex bundleStartRecordListMutex_;
std::unordered_map<std::string, std::vector<std::pair<int32_t, int32_t>>> bundleStartRecordMap_;
#endif
};
} // namespace AccessToken
} // namespace Security
@@ -41,6 +41,12 @@ public:
int32_t AddPermissionUsedRecordAsync(const AddPermParamInfoParcel& infoParcel) override;
int32_t StartUsingPermission(const PermissionUsedTypeInfoParcel &infoParcel,
const sptr<IRemoteObject>& anonyStub) override;
#ifdef PRIVACY_BUNDLE_START_STOP_ENABLE
int32_t StartUsingPermission(
const std::string& bundleName, const std::string& permissionName,
const sptr<IRemoteObject>& anonyStub) override;
int32_t StopUsingPermission(const std::string& bundleName, const std::string& permissionName) override;
#endif
int32_t StartUsingPermissionCallback(const PermissionUsedTypeInfoParcel &infoParcel,
const sptr<IRemoteObject>& callback, const sptr<IRemoteObject>& anonyStub) override;
int32_t SetPermissionUsedRecordToggleStatus(int32_t userID, bool status) override;
@@ -62,7 +68,7 @@ public:
int32_t GetPermissionUsedRecordsAsync(
const PermissionUsedRequestParcel& request, const sptr<OnPermissionUsedRecordCallback>& callback) override;
int32_t RegisterPermActiveStatusCallback(
const std::vector<std::string>& permList, const sptr<IRemoteObject>& callback) override;
const std::vector<std::string>& permList, const sptr<IRemoteObject>& callback, int32_t type) override;
int32_t UnRegisterPermActiveStatusCallback(const sptr<IRemoteObject>& callback) override;
int32_t IsAllowedUsingPermission(
AccessTokenID tokenId, const std::string& permissionName, int32_t pid, bool& isAllowed) override;
@@ -79,7 +79,8 @@ std::shared_ptr<AccessEventHandler> ActiveStatusCallbackManager::GetEventHandler
#endif
int32_t ActiveStatusCallbackManager::AddCallback(
AccessTokenID registerTokenId, const std::vector<std::string>& permList, const sptr<IRemoteObject>& callback)
AccessTokenID registerTokenId, const std::vector<std::string>& permList, const sptr<IRemoteObject>& callback,
int32_t registerType)
{
if (callback == nullptr) {
LOGE(PRI_DOMAIN, PRI_TAG, "Input is nullptr");
@@ -97,12 +98,7 @@ int32_t ActiveStatusCallbackManager::AddCallback(
return PrivacyError::ERR_ADD_DEATH_RECIPIENT_FAILED;
}
CallbackData recordInstance;
recordInstance.registerTokenId = registerTokenId;
recordInstance.callbackObject_ = callback;
recordInstance.permList_ = permList;
callbackDataList_.emplace_back(recordInstance);
callbackDataList_.emplace_back(registerTokenId, permList, callback, registerType);
LOGI(PRI_DOMAIN, PRI_TAG, "RecordInstance is added");
return RET_SUCCESS;
@@ -141,13 +137,23 @@ bool ActiveStatusCallbackManager::NeedCalled(const std::vector<std::string>& per
[permName](const std::string& perm) { return perm == permName; });
}
bool ActiveStatusCallbackManager::NeedNotify(CallbackRegisterType registerType, CallbackRegisterType sourceType) const
{
if (registerType == CallbackRegisterType::ALL) {
return true;
}
return registerType == sourceType;
}
void ActiveStatusCallbackManager::ActiveStatusChange(ActiveChangeResponse& info)
void ActiveStatusCallbackManager::ActiveStatusChange(ActiveChangeResponse& info, CallbackRegisterType sourceType)
{
std::vector<sptr<IRemoteObject>> list;
{
std::lock_guard<std::mutex> lock(mutex_);
for (auto it = callbackDataList_.begin(); it != callbackDataList_.end(); ++it) {
if (!NeedNotify(static_cast<CallbackRegisterType>(it->registerType_), sourceType)) {
continue;
}
std::vector<std::string> permList = (*it).permList_;
if (!NeedCalled(permList, info.permissionName)) {
LOGI(PRI_DOMAIN, PRI_TAG, "TokenId %{public}u, perm %{public}s", info.tokenID,
@@ -173,7 +179,7 @@ void ActiveStatusCallbackManager::ActiveStatusChange(ActiveChangeResponse& info)
}
}
void ActiveStatusCallbackManager::ExecuteCallbackAsync(ActiveChangeResponse& info)
void ActiveStatusCallbackManager::ExecuteCallbackAsync(ActiveChangeResponse& info, CallbackRegisterType sourceType)
{
#ifdef EVENTHANDLER_ENABLE
auto eventHandler = GetEventHandler();
@@ -184,8 +190,8 @@ void ActiveStatusCallbackManager::ExecuteCallbackAsync(ActiveChangeResponse& inf
std::string taskName = info.permissionName + std::to_string(info.tokenID);
LOGI(PRI_DOMAIN, PRI_TAG, "Add permission task name:%{public}s", taskName.c_str());
std::function<void()> task = ([info]() mutable {
ActiveStatusCallbackManager::GetInstance().ActiveStatusChange(info);
std::function<void()> task = ([info, sourceType]() mutable {
ActiveStatusCallbackManager::GetInstance().ActiveStatusChange(info, sourceType);
LOGI(PRI_DOMAIN, PRI_TAG, "deviceId: %{public}s, "
"token: %{public}u, pid: %{public}d, permName: %{public}s, changeType: %{public}d, ActiveStatusChange end",
ConstantCommon::EncryptDevId(info.deviceId).c_str(),
@@ -63,7 +63,6 @@ namespace Security {
namespace AccessToken {
namespace {
static const int32_t VALUE_MAX_LEN = 32;
static constexpr int32_t MAX_PERMISSION_NAME_LENGTH = 256;
constexpr const char* CAMERA_PERMISSION_NAME = "ohos.permission.CAMERA";
constexpr const char* CAMERA_BACKGROUND_PERMISSION_NAME = "ohos.permission.CAMERA_BACKGROUND";
constexpr const char* MICROPHONE_PERMISSION_NAME = "ohos.permission.MICROPHONE";
@@ -92,12 +91,13 @@ static const uint32_t MAX_PERMISSION_USED_TYPE_SIZE = 20;
#endif
constexpr const char* EDM_PROCESS_NAME = "edm";
std::recursive_mutex g_instanceMutex;
}
bool IsPermAddCallbackSupported(const std::string& permissionName)
static bool IsPermAddCallbackSupported(const std::string& permissionName)
{
return g_supportAddCallbackPermList.find(permissionName) != g_supportAddCallbackPermList.end();
}
}
PermissionRecordManager& PermissionRecordManager::GetInstance()
{
static PermissionRecordManager* instance = nullptr;
@@ -927,7 +927,7 @@ void PermissionRecordManager::CallbackRemoteExecute(const RemoteContinuousPermis
info.remoteDeviceName = remoteDeviceName;
info.type = type;
ActiveStatusCallbackManager::GetInstance().ExecuteCallbackAsync(info);
ActiveStatusCallbackManager::GetInstance().ExecuteCallbackAsync(info, CallbackRegisterType::TOKEN_ONLY);
}
int32_t PermissionRecordManager::AddRecordToStartRemoteList(
@@ -1039,7 +1039,7 @@ bool PermissionRecordManager::ToRemoveRemoteRecord(
for (auto it = startRemoteRecordList_.begin(); it != startRemoteRecordList_.end();) {
if (((*it).*isEqualFunc)(targetRecord)) {
std::string perm;
Constant::TransferOpcodeToPermission(it->opCode, perm);
(void)Constant::TransferOpcodeToPermission(it->opCode, perm);
RemoteContinuousPermissionRecord newRecord = {
.opCode = it->opCode,
.callerPid = it->callerPid,
@@ -1065,6 +1065,7 @@ bool PermissionRecordManager::ToRemoveRemoteRecord(
}
return res;
}
#endif
int32_t PermissionRecordManager::SetPermissionUsedRecordToggleStatus(int32_t userID, bool status)
@@ -1595,40 +1596,41 @@ void PermissionRecordManager::GetCurrUsingPermInfo(std::vector<CurrUsingPermInfo
{
{
std::lock_guard<std::mutex> lock(startRecordListMutex_);
for (auto it = startRecordList_.begin(); it != startRecordList_.end(); ++it) {
for (const auto& record : startRecordList_) {
std::string perm;
Constant::TransferOpcodeToPermission(it->opCode, perm);
ActiveChangeResponse info;
info.callingTokenID = it->callertokenId;
info.tokenID = it->tokenId;
info.permissionName = perm;
info.deviceId = "";
info.type = static_cast<ActiveChangeType>(it->status);
info.usedType = it->usedType;
info.pid = it->pid;
infoList.emplace_back(info);
(void)Constant::TransferOpcodeToPermission(record.opCode, perm);
infoList.emplace_back(record.callertokenId, record.tokenId, perm,
static_cast<ActiveChangeType>(record.status), record.usedType, record.pid);
LOGI(PRI_DOMAIN, PRI_TAG, "TokenId %{public}d using permission %{public}s, "
"status %{public}d, type %{public}d, pid %{public}d, callerPid %{public}d.", it->tokenId,
perm.c_str(), it->status, it->usedType, it->pid, it->callerPid);
"status %{public}d, type %{public}d, pid %{public}d, callerPid %{public}d.", record.tokenId,
perm.c_str(), record.status, record.usedType, record.pid, record.callerPid);
}
}
#ifdef PRIVACY_BUNDLE_START_STOP_ENABLE
{
std::lock_guard<std::mutex> lock(bundleStartRecordListMutex_);
for (const auto& item : bundleStartRecordMap_) {
for (const auto& record : item.second) {
std::string perm;
(void)Constant::TransferOpcodeToPermission(record.first, perm);
infoList.emplace_back(item.first, perm);
LOGI(PRI_DOMAIN, PRI_TAG, "Bundle %{public}s using permission %{public}s, callerPid %{public}d.",
item.first.c_str(), perm.c_str(), record.second);
}
}
}
#endif
#ifdef REMOTE_PRIVACY_ENABLE
{
std::lock_guard<std::mutex> lock(startRemoteRecordListMutex_);
for (auto it = startRemoteRecordList_.begin(); it != startRemoteRecordList_.end(); ++it) {
for (const auto& record : startRemoteRecordList_) {
std::string perm;
Constant::TransferOpcodeToPermission(it->opCode, perm);
ActiveChangeResponse info;
info.permissionName = perm;
info.type = ActiveChangeType::PERM_REMOTE_USING;
info.isRemote = true;
info.deviceId = uniqueDeviceId_;
info.remoteDeviceName = uniqueDeviceName_;
infoList.emplace_back(info);
(void)Constant::TransferOpcodeToPermission(record.opCode, perm);
infoList.emplace_back(perm, uniqueDeviceId_, uniqueDeviceName_);
LOGI(PRI_DOMAIN, PRI_TAG, "deviceId: %{public}s, "
"using permission %{public}s, type %{public}d, callerPid %{public}d.",
ConstantCommon::EncryptDevId(info.deviceId).c_str(), perm.c_str(), info.type, it->callerPid);
ConstantCommon::EncryptDevId(uniqueDeviceId_).c_str(), perm.c_str(),
ActiveChangeType::PERM_REMOTE_USING, record.callerPid);
}
}
#endif
@@ -1636,31 +1638,51 @@ void PermissionRecordManager::GetCurrUsingPermInfo(std::vector<CurrUsingPermInfo
int32_t PermissionRecordManager::CheckPermissionInUse(const std::string& permissionName, bool& isUsing)
{
std::lock_guard<std::mutex> lock(startRecordListMutex_);
// Validate permission name parameter
if (permissionName.empty() || permissionName.length() > MAX_PERMISSION_NAME_LENGTH) {
LOGE(PRI_DOMAIN, PRI_TAG, "Permission name is empty or exceeds max length: %{public}zu.",
permissionName.length());
return PrivacyError::ERR_PARAM_INVALID;
}
// Check if permission exists
int32_t opCode;
if (!Constant::TransferPermissionToOpcode(permissionName, opCode)) {
LOGE(PRI_DOMAIN, PRI_TAG, "Permission(%{public}s) is not exist", permissionName.c_str());
return PrivacyError::ERR_PERMISSION_NOT_EXIST;
}
// Iterate and check if opcode is in use
for (auto it = startRecordList_.begin(); it != startRecordList_.end(); ++it) {
if (it->opCode == opCode && it->status != PERM_INACTIVE) {
isUsing = true;
LOGI(PRI_DOMAIN, PRI_TAG, "Permission %{public}s (opcode %{public}d) isUsing: %{public}d",
permissionName.c_str(), opCode, isUsing);
return RET_SUCCESS;
{
std::lock_guard<std::mutex> lock(startRecordListMutex_);
for (auto it = startRecordList_.begin(); it != startRecordList_.end(); ++it) {
if (it->opCode == opCode && it->status != PERM_INACTIVE) {
isUsing = true;
LOGI(PRI_DOMAIN, PRI_TAG, "Permission %{public}s (opcode %{public}d) isUsing: %{public}d",
permissionName.c_str(), opCode, isUsing);
return RET_SUCCESS;
}
}
}
#ifdef PRIVACY_BUNDLE_START_STOP_ENABLE
{
std::lock_guard<std::mutex> lock(bundleStartRecordListMutex_);
for (const auto& item : bundleStartRecordMap_) {
for (const auto& record : item.second) {
if (record.first == opCode) {
isUsing = true;
LOGI(PRI_DOMAIN, PRI_TAG, "Bundle permission %{public}s (opcode %{public}d) isUsing: %{public}d",
permissionName.c_str(), opCode, isUsing);
return RET_SUCCESS;
}
}
}
}
#endif
#ifdef REMOTE_PRIVACY_ENABLE
{
std::lock_guard<std::mutex> lock(startRemoteRecordListMutex_);
for (const auto& record : startRemoteRecordList_) {
if (record.opCode == opCode) {
isUsing = true;
LOGI(PRI_DOMAIN, PRI_TAG, "Remote permission %{public}s (opcode %{public}d) isUsing: %{public}d",
permissionName.c_str(), opCode, isUsing);
return RET_SUCCESS;
}
}
}
#endif
isUsing = false;
LOGI(PRI_DOMAIN, PRI_TAG, "Permission %{public}s (opcode %{public}d) isUsing: %{public}d",
@@ -1676,7 +1698,7 @@ void PermissionRecordManager::ExecuteAndUpdateRecord(uint32_t tokenId, int32_t p
for (auto it = startRecordList_.begin(); it != startRecordList_.end();) {
if ((it->tokenId == tokenId) && ((it->status) != PERM_INACTIVE) && ((it->status) != status)) {
std::string perm;
Constant::TransferOpcodeToPermission(it->opCode, perm);
(void)Constant::TransferOpcodeToPermission(it->opCode, perm);
if ((GetMuteStatus(perm, EDM)) || (!GetGlobalSwitchStatus(perm))) {
++it;
continue;
@@ -1809,6 +1831,24 @@ void PermissionRecordManager::RemoveRecordFromStartListByCallerPid(int32_t calle
ContinuousPermissionRecord record = {0};
record.callerPid = callerPid;
(void) ToRemoveRecord(record, &ContinuousPermissionRecord::IsEqualCallerPid);
#ifdef PRIVACY_BUNDLE_START_STOP_ENABLE
{
std::lock_guard<std::mutex> lock(bundleStartRecordListMutex_);
for (auto mapIt = bundleStartRecordMap_.begin(); mapIt != bundleStartRecordMap_.end();) {
auto& records = mapIt->second;
records.erase(std::remove_if(records.begin(), records.end(),
[callerPid](const std::pair<int32_t, int32_t>& recordInfo) {
return recordInfo.second == callerPid;
}), records.end());
if (records.empty()) {
mapIt = bundleStartRecordMap_.erase(mapIt);
continue;
}
++mapIt;
}
}
#endif
#ifdef REMOTE_PRIVACY_ENABLE
RemoteContinuousPermissionRecord targetRecord;
targetRecord.callerPid = callerPid;
@@ -1831,7 +1871,7 @@ bool PermissionRecordManager::ToRemoveRecord(const ContinuousPermissionRecord& t
}
PermissionRecordSet::GetInActiveUniqueRecord(startRecordList_, removeList, inactiveList);
for (const auto& record: inactiveList) {
Constant::TransferOpcodeToPermission(record.opCode, perm);
(void)Constant::TransferOpcodeToPermission(record.opCode, perm);
ContinuousPermissionRecord newRecord;
newRecord.tokenId = record.tokenId;
newRecord.status = PERM_INACTIVE;
@@ -1869,7 +1909,8 @@ void PermissionRecordManager::CallbackExecute(
info.usedType = type;
info.pid = record.pid;
ActiveStatusCallbackManager::GetInstance().ExecuteCallbackAsync(info);
ActiveStatusCallbackManager::GetInstance().ExecuteCallbackAsync(
info, CallbackRegisterType::TOKEN_ONLY);
}
void PermissionRecordManager::ExecutePermAddCallbackAsync(
@@ -1890,7 +1931,7 @@ void PermissionRecordManager::ExecutePermAddCallbackAsync(
callbackInfo.deviceId = "";
callbackInfo.remoteDeviceName = "";
callbackInfo.extra = info.extra;
ActiveStatusCallbackManager::GetInstance().ExecuteCallbackAsync(callbackInfo);
ActiveStatusCallbackManager::GetInstance().ExecuteCallbackAsync(callbackInfo, CallbackRegisterType::TOKEN_ONLY);
}
bool PermissionRecordManager::GetGlobalSwitchStatus(const std::string& permissionName)
@@ -2156,21 +2197,131 @@ int32_t PermissionRecordManager::StopUsingPermission(
return RemoveRecordFromStartList(tokenId, pid, permissionName, callerPid);
}
#ifdef PRIVACY_BUNDLE_START_STOP_ENABLE
int32_t PermissionRecordManager::StartUsingPermission(
const std::string& bundleName, const std::string& permissionName, int32_t callerPid)
{
if (!DataValidator::IsBundleNameValid(bundleName) || !DataValidator::IsPermissionNameValid(permissionName)) {
return PrivacyError::ERR_PARAM_INVALID;
}
int32_t opCode = 0;
if (!Constant::TransferPermissionToOpcode(permissionName, opCode)) {
LOGE(PRI_DOMAIN, PRI_TAG, "Invalid permission(%{public}s)", permissionName.c_str());
return PrivacyError::ERR_PERMISSION_NOT_EXIST;
}
InitializeMuteState(permissionName);
if (IsEdmMuteOrDisable(permissionName)) {
LOGE(PRI_DOMAIN, PRI_TAG, "EDM not allow.");
return PrivacyError::ERR_EDM_POLICY_CHECK_FAILED;
}
if (!Register()) {
return PrivacyError::ERR_MALLOC_FAILED;
}
std::lock_guard<std::mutex> lock(bundleStartRecordListMutex_);
auto mapIt = bundleStartRecordMap_.find(bundleName);
if (mapIt == bundleStartRecordMap_.end()) {
mapIt = bundleStartRecordMap_.emplace(bundleName, std::vector<std::pair<int32_t, int32_t>> {}).first;
}
auto& records = mapIt->second;
const auto isSameRecord = [opCode, callerPid](const std::pair<int32_t, int32_t>& record) {
return (record.first == opCode) && (record.second == callerPid);
};
if (std::find_if(records.begin(), records.end(), isSameRecord) != records.end()) {
LOGE(PRI_DOMAIN, PRI_TAG, "Bundle in use: %{public}s, op=%{public}d, caller=%{public}d",
bundleName.c_str(), opCode, callerPid);
return PrivacyError::ERR_PERMISSION_ALREADY_START_USING;
}
records.emplace_back(opCode, callerPid);
ActiveChangeResponse info;
info.callingTokenID = IPCSkeleton::GetCallingTokenID();
info.permissionName = permissionName;
info.type = ActiveChangeType::PERM_ACTIVE_IN_FOREGROUND;
info.usedType = NORMAL_TYPE;
info.bundleName = bundleName;
ActiveStatusCallbackManager::GetInstance().ExecuteCallbackAsync(info, CallbackRegisterType::ALL);
return Constant::SUCCESS;
}
int32_t PermissionRecordManager::StopUsingPermission(
const std::string& bundleName, const std::string& permissionName, int32_t callerPid)
{
if (!DataValidator::IsBundleNameValid(bundleName) || !DataValidator::IsPermissionNameValid(permissionName)) {
return PrivacyError::ERR_PARAM_INVALID;
}
int32_t opCode = 0;
if (!Constant::TransferPermissionToOpcode(permissionName, opCode)) {
LOGE(PRI_DOMAIN, PRI_TAG, "Invalid permission(%{public}s)", permissionName.c_str());
return PrivacyError::ERR_PERMISSION_NOT_EXIST;
}
std::lock_guard<std::mutex> lock(bundleStartRecordListMutex_);
auto mapIt = bundleStartRecordMap_.find(bundleName);
if (mapIt == bundleStartRecordMap_.end()) {
LOGE(PRI_DOMAIN, PRI_TAG, "Bundle not started: %{public}s, op=%{public}d, caller=%{public}d",
bundleName.c_str(), opCode, callerPid);
return PrivacyError::ERR_PERMISSION_NOT_START_USING;
}
auto& records = mapIt->second;
auto recordIt = std::find_if(records.begin(), records.end(),
[opCode, callerPid](const std::pair<int32_t, int32_t>& record) {
return (record.first == opCode) && (record.second == callerPid);
});
if (recordIt == records.end()) {
LOGE(PRI_DOMAIN, PRI_TAG, "Bundle not started: %{public}s, op=%{public}d, caller=%{public}d",
bundleName.c_str(), opCode, callerPid);
return PrivacyError::ERR_PERMISSION_NOT_START_USING;
}
records.erase(recordIt);
if (records.empty()) {
bundleStartRecordMap_.erase(mapIt);
}
ActiveChangeResponse info;
info.callingTokenID = IPCSkeleton::GetCallingTokenID();
info.permissionName = permissionName;
info.type = ActiveChangeType::PERM_INACTIVE;
info.usedType = NORMAL_TYPE;
info.bundleName = bundleName;
ActiveStatusCallbackManager::GetInstance().ExecuteCallbackAsync(info, CallbackRegisterType::ALL);
return Constant::SUCCESS;
}
#endif
bool PermissionRecordManager::HasCallerInStartList(int32_t callerPid)
{
{
std::lock_guard<std::mutex> lock(startRecordListMutex_);
for (auto it = startRecordList_.begin(); it != startRecordList_.end(); ++it) {
if (it->callerPid == callerPid) {
for (const auto& record : startRecordList_) {
if (record.callerPid == callerPid) {
return true;
}
}
}
#ifdef PRIVACY_BUNDLE_START_STOP_ENABLE
{
std::lock_guard<std::mutex> lock(bundleStartRecordListMutex_);
for (const auto& item : bundleStartRecordMap_) {
for (const auto& record : item.second) {
if (record.second == callerPid) {
return true;
}
}
}
}
#endif
#ifdef REMOTE_PRIVACY_ENABLE
{
std::lock_guard<std::mutex> lock(startRemoteRecordListMutex_);
for (auto it = startRemoteRecordList_.begin(); it != startRemoteRecordList_.end(); ++it) {
if (it->callerPid == callerPid) {
for (const auto& record : startRemoteRecordList_) {
if (record.callerPid == callerPid) {
return true;
}
}
@@ -2404,14 +2555,15 @@ bool PermissionRecordManager::GetMuteStatus(const std::string& permissionName, i
}
int32_t PermissionRecordManager::RegisterPermActiveStatusCallback(
AccessTokenID regiterTokenId, const std::vector<std::string>& permList, const sptr<IRemoteObject>& callback)
AccessTokenID regiterTokenId, const std::vector<std::string>& permList, const sptr<IRemoteObject>& callback,
int32_t type)
{
std::vector<std::string> permListRes;
int32_t res = PermissionListFilter(permList, permListRes);
if (res != Constant::SUCCESS) {
return res;
}
return ActiveStatusCallbackManager::GetInstance().AddCallback(regiterTokenId, permListRes, callback);
return ActiveStatusCallbackManager::GetInstance().AddCallback(regiterTokenId, permListRes, callback, type);
}
int32_t PermissionRecordManager::UnRegisterPermActiveStatusCallback(const sptr<IRemoteObject>& callback)
@@ -2424,7 +2576,8 @@ void PermissionRecordManager::AddDataValueToResults(const GenericValues value,
{
PermissionUsedTypeInfo info;
info.tokenId = static_cast<AccessTokenID>(value.GetInt(PrivacyFiledConst::FIELD_TOKEN_ID));
Constant::TransferOpcodeToPermission(value.GetInt(PrivacyFiledConst::FIELD_PERMISSION_CODE), info.permissionName);
(void)Constant::TransferOpcodeToPermission(value.GetInt(PrivacyFiledConst::FIELD_PERMISSION_CODE),
info.permissionName);
uint32_t type = static_cast<uint32_t>(value.GetInt(PrivacyFiledConst::FIELD_USED_TYPE));
if ((type & NORMAL_TYPE_ADD_VALUE) == NORMAL_TYPE_ADD_VALUE) { // normal first
info.type = PermissionUsedType::NORMAL_TYPE;
@@ -55,8 +55,15 @@ constexpr const char* SET_MUTE_POLICY = "ohos.permission.SET_MUTE_POLICY";
constexpr const char* MANAGE_EDM_POLICY = "ohos.permission.MANAGE_EDM_POLICY";
constexpr const char* GET_PERMISSION_POLICY = "ohos.permission.GET_PERMISSION_POLICY";
static const int32_t SA_ID_PRIVACY_MANAGER_SERVICE = 3505;
static constexpr int32_t MAX_PERMISSION_NAME_LENGTH = 256;
static const uint32_t PERM_LIST_SIZE_MAX = 1024;
static const int32_t RETRY_COUNT = 128;
bool IsValidCallbackRegisterType(int32_t type)
{
return (type == static_cast<int32_t>(CallbackRegisterType::ALL)) ||
(type == static_cast<int32_t>(CallbackRegisterType::TOKEN_ONLY));
}
static const int32_t RETRY_TIMES_MS = 500; // 0.5s
static const int32_t ASYNC_RETRY_COUNT = 43200; // 30d * 24h * 60m
static const int32_t ASYNC_RETRY_TIMES_MS = 60 * 1000; // 1min
@@ -188,6 +195,10 @@ void PrivacyManagerService::ProcessProxyDeathStub(const sptr<IRemoteObject>& ano
void PrivacyManagerService::ReleaseDeathStub(int32_t callerPid)
{
if (PermissionRecordManager::GetInstance().HasCallerInStartList(callerPid)) {
return;
}
LOGI(PRI_DOMAIN, PRI_TAG, "No permission record from caller = %{public}d", callerPid);
std::shared_ptr<ProxyDeathParam> param = std::make_shared<PrivacyManagerProxyDeathParam>(callerPid);
if (param == nullptr) {
LOGE(PRI_DOMAIN, PRI_TAG, "Create param failed.");
@@ -256,10 +267,7 @@ int32_t PrivacyManagerService::StopUsingPermission(
if (ret != Constant::SUCCESS) {
return ret;
}
if (!PermissionRecordManager::GetInstance().HasCallerInStartList(callerPid)) {
LOGI(PRI_DOMAIN, PRI_TAG, "No permission record from caller = %{public}d", callerPid);
ReleaseDeathStub(callerPid);
}
ReleaseDeathStub(callerPid);
return ret;
}
@@ -300,10 +308,7 @@ int32_t PrivacyManagerService::StopRemoteUsingPermission(const std::string& remo
if (ret != Constant::SUCCESS) {
return ret;
}
if (!PermissionRecordManager::GetInstance().HasCallerInStartList(callerPid)) {
LOGI(PRI_DOMAIN, PRI_TAG, "No permission record from caller = %{public}d", callerPid);
ReleaseDeathStub(callerPid);
}
ReleaseDeathStub(callerPid);
return ret;
}
@@ -360,6 +365,50 @@ int32_t PrivacyManagerService::GetRemotePermissionUsedRecords(
}
#endif
#ifdef PRIVACY_BUNDLE_START_STOP_ENABLE
int32_t PrivacyManagerService::StartUsingPermission(
const std::string& bundleName, const std::string& permissionName, const sptr<IRemoteObject>& anonyStub)
{
uint32_t callingTokenID = IPCSkeleton::GetCallingTokenID();
if ((AccessTokenKit::GetTokenTypeFlag(callingTokenID) == TOKEN_HAP) && (!IsSystemAppCalling())) {
return PrivacyError::ERR_NOT_SYSTEM_APP;
}
if (!VerifyPermission(PERMISSION_USED_STATS)) {
return PrivacyError::ERR_PERMISSION_DENIED;
}
int32_t callerPid = IPCSkeleton::GetCallingPid();
LOGI(PRI_DOMAIN, PRI_TAG, "Bundle start: %{public}s, %{public}s, %{public}d.",
bundleName.c_str(), permissionName.c_str(), callerPid);
ProcessProxyDeathStub(anonyStub, callerPid);
return PermissionRecordManager::GetInstance().StartUsingPermission(bundleName, permissionName, callerPid);
}
#endif
#ifdef PRIVACY_BUNDLE_START_STOP_ENABLE
int32_t PrivacyManagerService::StopUsingPermission(
const std::string& bundleName, const std::string& permissionName)
{
uint32_t callingTokenID = IPCSkeleton::GetCallingTokenID();
if ((AccessTokenKit::GetTokenTypeFlag(callingTokenID) == TOKEN_HAP) && (!IsSystemAppCalling())) {
return PrivacyError::ERR_NOT_SYSTEM_APP;
}
if (!VerifyPermission(PERMISSION_USED_STATS)) {
return PrivacyError::ERR_PERMISSION_DENIED;
}
int32_t callerPid = IPCSkeleton::GetCallingPid();
LOGI(PRI_DOMAIN, PRI_TAG, "Bundle stop: %{public}s, %{public}s, %{public}d.",
bundleName.c_str(), permissionName.c_str(), callerPid);
int32_t ret = PermissionRecordManager::GetInstance().StopUsingPermission(bundleName, permissionName, callerPid);
if (ret != Constant::SUCCESS) {
return ret;
}
ReleaseDeathStub(callerPid);
return ret;
}
#endif
int32_t PrivacyManagerService::RemovePermissionUsedRecords(AccessTokenID tokenId)
{
uint32_t callingTokenID = IPCSkeleton::GetCallingTokenID();
@@ -417,7 +466,7 @@ int32_t PrivacyManagerService::GetPermissionUsedRecordsAsync(
}
int32_t PrivacyManagerService::RegisterPermActiveStatusCallback(
const std::vector<std::string>& permList, const sptr<IRemoteObject>& callback)
const std::vector<std::string>& permList, const sptr<IRemoteObject>& callback, int32_t type)
{
uint32_t callingTokenID = IPCSkeleton::GetCallingTokenID();
if ((AccessTokenKit::GetTokenTypeFlag(callingTokenID) == TOKEN_HAP) && (!IsSystemAppCalling())) {
@@ -431,9 +480,12 @@ int32_t PrivacyManagerService::RegisterPermActiveStatusCallback(
LOGE(PRI_DOMAIN, PRI_TAG, "PermList oversize");
return PrivacyError::ERR_OVERSIZE;
}
if (!IsValidCallbackRegisterType(type)) {
return PrivacyError::ERR_PARAM_INVALID;
}
return PermissionRecordManager::GetInstance().RegisterPermActiveStatusCallback(
IPCSkeleton::GetCallingTokenID(), permList, callback);
IPCSkeleton::GetCallingTokenID(), permList, callback, type);
}
int32_t PrivacyManagerService::ResponseDumpCommand(int32_t fd, const std::vector<std::u16string>& args)
@@ -654,6 +706,9 @@ int32_t PrivacyManagerService::CheckPermissionInUse(const std::string& permissio
if (!VerifyPermission(PERMISSION_USED_STATS)) {
return PrivacyError::ERR_PERMISSION_DENIED;
}
if (permissionName.empty() || permissionName.length() > MAX_PERMISSION_NAME_LENGTH) {
return PrivacyError::ERR_PARAM_INVALID;
}
return PermissionRecordManager::GetInstance().CheckPermissionInUse(permissionName, isUsing);
}
@@ -420,7 +420,8 @@ HWTEST_F(PermissionRecordManagerTest, OnRemoteDied001, TestSize.Level4)
permList.emplace_back("ohos.permission.CAMERA");
wptr<IRemoteObject> remote = new (std::nothrow) PermActiveStatusChangeCallbackTest();
callback = remote.promote();
ActiveStatusCallbackManager::GetInstance().AddCallback(GetSelfTokenID(), permList, callback);
ActiveStatusCallbackManager::GetInstance().AddCallback(
GetSelfTokenID(), permList, callback, static_cast<int32_t>(CallbackRegisterType::TOKEN_ONLY));
ASSERT_EQ(static_cast<uint32_t>(1), ActiveStatusCallbackManager::GetInstance().callbackDataList_.size());
recipient->OnRemoteDied(remote); // remote is not nullptr
ASSERT_EQ(static_cast<uint32_t>(0), ActiveStatusCallbackManager::GetInstance().callbackDataList_.size());
@@ -88,6 +88,21 @@ void PermActiveStatusChangeCallbackTest1::ActiveStatusChangeCallback(ActiveChang
{
}
class PermActiveStatusCountCallbackTest : public PermActiveStatusChangeCallbackStub {
public:
PermActiveStatusCountCallbackTest() = default;
virtual ~PermActiveStatusCountCallbackTest() = default;
void ActiveStatusChangeCallback(ActiveChangeResponse& result) override
{
++count_;
type_ = result.type;
}
int32_t count_ = 0;
ActiveChangeType type_ = PERM_INACTIVE;
};
/*
* @tc.name: AddCallback001
* @tc.desc: AddCallback mock function test
@@ -105,16 +120,19 @@ HWTEST_F(ActiveStatusCallbackManagerTest, AddCallback001, TestSize.Level0)
std::vector<std::string> permList;
permList.emplace_back("ohos.permission.CAMERA");
int32_t ret = ActiveStatusCallbackManager::GetInstance().AddCallback(GetSelfTokenID(), permList, callback);
int32_t ret = ActiveStatusCallbackManager::GetInstance().AddCallback(
GetSelfTokenID(), permList, callback, static_cast<int32_t>(CallbackRegisterType::TOKEN_ONLY));
EXPECT_EQ(ret, ERR_PARAM_INVALID);
wptr<IRemoteObject> remote = new (std::nothrow) PermActiveStatusChangeCallbackTest();
callback = remote.promote();
ret = ActiveStatusCallbackManager::GetInstance().AddCallback(GetSelfTokenID(), permList, callback);
ret = ActiveStatusCallbackManager::GetInstance().AddCallback(
GetSelfTokenID(), permList, callback, static_cast<int32_t>(CallbackRegisterType::TOKEN_ONLY));
EXPECT_EQ(ret, RET_SUCCESS);
g_isAddSucc = false;
ret = ActiveStatusCallbackManager::GetInstance().AddCallback(GetSelfTokenID(), permList, callback);
ret = ActiveStatusCallbackManager::GetInstance().AddCallback(
GetSelfTokenID(), permList, callback, static_cast<int32_t>(CallbackRegisterType::TOKEN_ONLY));
EXPECT_EQ(ret, ERR_ADD_DEATH_RECIPIENT_FAILED);
// recovery
@@ -140,12 +158,83 @@ HWTEST_F(ActiveStatusCallbackManagerTest, AddCallback002, TestSize.Level0)
wptr<IRemoteObject> remote = new (std::nothrow) PermActiveStatusChangeCallbackTest1();
callback = remote.promote();
int32_t ret = ActiveStatusCallbackManager::GetInstance().AddCallback(GetSelfTokenID(), permList, callback);
int32_t ret = ActiveStatusCallbackManager::GetInstance().AddCallback(
GetSelfTokenID(), permList, callback, static_cast<int32_t>(CallbackRegisterType::TOKEN_ONLY));
EXPECT_EQ(ret, RET_SUCCESS);
// recovery
ActiveStatusCallbackManager::GetInstance().callbackDataList_ = callbackDataList;
}
/*
* @tc.name: AddCallback003
* @tc.desc: AddCallback stores ALL register type correctly.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(ActiveStatusCallbackManagerTest, AddCallback003, TestSize.Level0)
{
std::vector<CallbackData> callbackDataList = ActiveStatusCallbackManager::GetInstance().callbackDataList_;
ActiveStatusCallbackManager::GetInstance().callbackDataList_.clear();
sptr<IRemoteObject> callback;
std::vector<std::string> permList;
permList.emplace_back("ohos.permission.CAMERA");
wptr<IRemoteObject> remote = new (std::nothrow) PermActiveStatusChangeCallbackTest1();
callback = remote.promote();
int32_t ret = ActiveStatusCallbackManager::GetInstance().AddCallback(
GetSelfTokenID(), permList, callback, static_cast<int32_t>(CallbackRegisterType::ALL));
ASSERT_EQ(ret, RET_SUCCESS);
ASSERT_EQ(1, ActiveStatusCallbackManager::GetInstance().callbackDataList_.size());
EXPECT_EQ(static_cast<int32_t>(CallbackRegisterType::ALL),
ActiveStatusCallbackManager::GetInstance().callbackDataList_[0].registerType_);
ActiveStatusCallbackManager::GetInstance().callbackDataList_ = callbackDataList;
}
/*
* @tc.name: ActiveStatusChangeByRegisterType001
* @tc.desc: Verify TOKEN_ONLY only receives token events and ALL receives supported source events.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(ActiveStatusCallbackManagerTest, ActiveStatusChangeByRegisterType001, TestSize.Level0)
{
std::vector<CallbackData> callbackDataList = ActiveStatusCallbackManager::GetInstance().callbackDataList_;
ActiveStatusCallbackManager::GetInstance().callbackDataList_.clear();
std::vector<std::string> permList = {"ohos.permission.CAMERA"};
sptr<PermActiveStatusCountCallbackTest> tokenCallback = new (std::nothrow) PermActiveStatusCountCallbackTest();
sptr<PermActiveStatusCountCallbackTest> allCallback = new (std::nothrow) PermActiveStatusCountCallbackTest();
ASSERT_NE(nullptr, tokenCallback);
ASSERT_NE(nullptr, allCallback);
auto& manager = ActiveStatusCallbackManager::GetInstance();
ASSERT_EQ(RET_SUCCESS, manager.AddCallback(
GetSelfTokenID(), permList, tokenCallback->AsObject(),
static_cast<int32_t>(CallbackRegisterType::TOKEN_ONLY)));
ASSERT_EQ(RET_SUCCESS, manager.AddCallback(
GetSelfTokenID(), permList, allCallback->AsObject(),
static_cast<int32_t>(CallbackRegisterType::ALL)));
ActiveChangeResponse info;
info.permissionName = "ohos.permission.CAMERA";
info.type = PERM_ACTIVE_IN_FOREGROUND;
manager.ActiveStatusChange(info, CallbackRegisterType::TOKEN_ONLY);
EXPECT_EQ(1, tokenCallback->count_);
EXPECT_EQ(1, allCallback->count_);
#ifdef PRIVACY_BUNDLE_START_STOP_ENABLE
// Bundle-level active status changes are dispatched with the ALL source type.
manager.ActiveStatusChange(info, CallbackRegisterType::ALL);
EXPECT_EQ(1, tokenCallback->count_);
EXPECT_EQ(2, allCallback->count_);
#endif
ActiveStatusCallbackManager::GetInstance().callbackDataList_ = callbackDataList;
}
} // namespace AccessToken
} // namespace Security
} // namespace OHOS
@@ -295,7 +295,7 @@ HWTEST_F(PermissionRecordManagerTest, RegisterPermActiveStatusCallback001, TestS
{
std::vector<std::string> permList = {"ohos.permission.CAMERA"};
ASSERT_EQ(PrivacyError::ERR_PARAM_INVALID, PermissionRecordManager::GetInstance().RegisterPermActiveStatusCallback(
GetSelfTokenID(), permList, nullptr));
GetSelfTokenID(), permList, nullptr, static_cast<int32_t>(CallbackRegisterType::TOKEN_ONLY)));
}
@@ -340,7 +340,8 @@ HWTEST_F(PermissionRecordManagerTest, RegisterPermActiveStatusCallback002, TestS
sptr<PermActiveStatusChangeCallback> callback = new (std::nothrow) PermActiveStatusChangeCallback();
ASSERT_NE(nullptr, callback);
ASSERT_EQ(RET_SUCCESS, PermissionRecordManager::GetInstance().RegisterPermActiveStatusCallback(
GetSelfTokenID(), permList, callback->AsObject()));
GetSelfTokenID(), permList, callback->AsObject(),
static_cast<int32_t>(CallbackRegisterType::TOKEN_ONLY)));
callbacks.emplace_back(callback);
}
@@ -348,7 +349,8 @@ HWTEST_F(PermissionRecordManagerTest, RegisterPermActiveStatusCallback002, TestS
ASSERT_NE(nullptr, callback);
ASSERT_EQ(PrivacyError::ERR_CALLBACKS_EXCEED_LIMITATION,
PermissionRecordManager::GetInstance().RegisterPermActiveStatusCallback(
GetSelfTokenID(), permList, callback->AsObject()));
GetSelfTokenID(), permList, callback->AsObject(),
static_cast<int32_t>(CallbackRegisterType::TOKEN_ONLY)));
for (size_t i = 0; i < callbacks.size(); ++i) {
ASSERT_EQ(RET_SUCCESS,
@@ -366,7 +368,7 @@ HWTEST_F(PermissionRecordManagerTest, UnRegisterPermActiveStatusCallback001, Tes
{
std::vector<std::string> permList = {"ohos.permission.CAMERA"};
ASSERT_EQ(PrivacyError::ERR_PARAM_INVALID, PermissionRecordManager::GetInstance().RegisterPermActiveStatusCallback(
GetSelfTokenID(), permList, nullptr));
GetSelfTokenID(), permList, nullptr, static_cast<int32_t>(CallbackRegisterType::TOKEN_ONLY)));
}
/*
@@ -439,8 +441,7 @@ HWTEST_F(PermissionRecordManagerTest, StartUsingPermissionTest003, TestSize.Leve
AccessTokenID tokenId = tokenIdEx.tokenIdExStruct.tokenID;
ASSERT_NE(INVALID_TOKENID, tokenId);
std::string permissionName = "ohos.permission.MICROPHONE";
ASSERT_EQ(PrivacyError::ERR_EDM_POLICY_CHECK_FAILED,
PermissionRecordManager::GetInstance().StartUsingPermission(
ASSERT_EQ(PrivacyError::ERR_EDM_POLICY_CHECK_FAILED, PermissionRecordManager::GetInstance().StartUsingPermission(
MakeInfo(tokenId, PID, permissionName), CALLER_PID));
std::string str = isMute ? "true" : "false";
SetParameter(EDM_MIC_MUTE_KEY, str.c_str());
@@ -468,7 +469,7 @@ HWTEST_F(PermissionRecordManagerTest, StartUsingPermissionTest004, TestSize.Leve
sptr<PermActiveStatusChangeCallback> callback = new (std::nothrow) PermActiveStatusChangeCallback();
ASSERT_NE(nullptr, callback);
ASSERT_EQ(RET_SUCCESS, PermissionRecordManager::GetInstance().RegisterPermActiveStatusCallback(
GetSelfTokenID(), permList, callback->AsObject()));
GetSelfTokenID(), permList, callback->AsObject(), static_cast<int32_t>(CallbackRegisterType::TOKEN_ONLY)));
AccessTokenIDEx tokenIdEx = PrivacyTestCommon::GetHapTokenIdFromBundle(g_InfoParms1.userID, g_InfoParms1.bundleName,
g_InfoParms1.instIndex);
@@ -508,7 +509,7 @@ HWTEST_F(PermissionRecordManagerTest, StartUsingPermissionTest005, TestSize.Leve
sptr<PermActiveStatusChangeCallback> callback = new (std::nothrow) PermActiveStatusChangeCallback();
ASSERT_NE(nullptr, callback);
ASSERT_EQ(RET_SUCCESS, PermissionRecordManager::GetInstance().RegisterPermActiveStatusCallback(
GetSelfTokenID(), permList, callback->AsObject()));
GetSelfTokenID(), permList, callback->AsObject(), static_cast<int32_t>(CallbackRegisterType::TOKEN_ONLY)));
AccessTokenIDEx tokenIdEx = PrivacyTestCommon::GetHapTokenIdFromBundle(g_InfoParms1.userID, g_InfoParms1.bundleName,
g_InfoParms1.instIndex);
@@ -549,7 +550,7 @@ HWTEST_F(PermissionRecordManagerTest, StartUsingPermissionTest006, TestSize.Leve
sptr<PermActiveStatusChangeCallback> callback = new (std::nothrow) PermActiveStatusChangeCallback();
EXPECT_NE(nullptr, callback);
EXPECT_EQ(RET_SUCCESS, PermissionRecordManager::GetInstance().RegisterPermActiveStatusCallback(
GetSelfTokenID(), permList, callback->AsObject()));
GetSelfTokenID(), permList, callback->AsObject(), static_cast<int32_t>(CallbackRegisterType::TOKEN_ONLY)));
AccessTokenIDEx tokenIdEx = PrivacyTestCommon::GetHapTokenIdFromBundle(g_InfoParms1.userID, g_InfoParms1.bundleName,
g_InfoParms1.instIndex);
@@ -608,7 +609,7 @@ HWTEST_F(PermissionRecordManagerTest, StartUsingPermissionTest008, TestSize.Leve
sptr<PermActiveStatusChangeCallback> callback = new (std::nothrow) PermActiveStatusChangeCallback();
ASSERT_NE(nullptr, callback);
ASSERT_EQ(RET_SUCCESS, PermissionRecordManager::GetInstance().RegisterPermActiveStatusCallback(
GetSelfTokenID(), permList, callback->AsObject()));
GetSelfTokenID(), permList, callback->AsObject(), static_cast<int32_t>(CallbackRegisterType::TOKEN_ONLY)));
AccessTokenIDEx tokenIdEx = PrivacyTestCommon::GetHapTokenIdFromBundle(g_InfoParms1.userID, g_InfoParms1.bundleName,
g_InfoParms1.instIndex);
@@ -715,7 +716,7 @@ HWTEST_F(PermissionRecordManagerTest, StartUsingPermissionTest010, TestSize.Leve
sptr<PermActiveStatusChangeCallback> callback = new (std::nothrow) PermActiveStatusChangeCallback();
ASSERT_NE(nullptr, callback);
ASSERT_EQ(RET_SUCCESS, PermissionRecordManager::GetInstance().RegisterPermActiveStatusCallback(
GetSelfTokenID(), permList, callback->AsObject()));
GetSelfTokenID(), permList, callback->AsObject(), static_cast<int32_t>(CallbackRegisterType::TOKEN_ONLY)));
AccessTokenIDEx tokenIdEx = PrivacyTestCommon::GetHapTokenIdFromBundle(g_InfoParms1.userID, g_InfoParms1.bundleName,
g_InfoParms1.instIndex);
@@ -825,7 +826,7 @@ HWTEST_F(PermissionRecordManagerTest, StartUsingPermissionTest012, TestSize.Leve
sptr<PermActiveStatusChangeCallback> callback = new (std::nothrow) PermActiveStatusChangeCallback();
ASSERT_NE(nullptr, callback);
ASSERT_EQ(RET_SUCCESS, PermissionRecordManager::GetInstance().RegisterPermActiveStatusCallback(
GetSelfTokenID(), permList, callback->AsObject()));
GetSelfTokenID(), permList, callback->AsObject(), static_cast<int32_t>(CallbackRegisterType::TOKEN_ONLY)));
AccessTokenIDEx tokenIdEx = PrivacyTestCommon::GetHapTokenIdFromBundle(g_InfoParms1.userID, g_InfoParms1.bundleName,
g_InfoParms1.instIndex);
AccessTokenID tokenId = tokenIdEx.tokenIdExStruct.tokenID;
@@ -1237,7 +1238,7 @@ HWTEST_F(PermissionRecordManagerTest, RegisterPermActiveStatusCallback003, TestS
permList.emplace_back("com.ohos.TEST");
// GetDefPermission != Constant::SUCCESS && listRes is empty && listSrc is not empty
ASSERT_EQ(PrivacyError::ERR_PARAM_INVALID, PermissionRecordManager::GetInstance().RegisterPermActiveStatusCallback(
GetSelfTokenID(), permList, nullptr));
GetSelfTokenID(), permList, nullptr, static_cast<int32_t>(CallbackRegisterType::TOKEN_ONLY)));
}
/*
@@ -1663,7 +1664,7 @@ HWTEST_F(PermissionRecordManagerTest, ProxyDeathTest002, TestSize.Level0)
}
/*
* @tc.name: PermissionRecordManagerTest
* @tc.name: HasCallerInStartList001
* @tc.desc: HasCallerInStartList test
* @tc.type: FUNC
* @tc.require:
@@ -1688,6 +1689,247 @@ HWTEST_F(PermissionRecordManagerTest, HasCallerInStartList001, TestSize.Level0)
ASSERT_FALSE(PermissionRecordManager::GetInstance().HasCallerInStartList(CALLER_PID));
}
#ifdef PRIVACY_BUNDLE_START_STOP_ENABLE
/*
* @tc.name: StartUsingPermissionBundle001
* @tc.desc: StartUsingPermission bundle function test
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(PermissionRecordManagerTest, StartUsingPermissionBundle001, TestSize.Level0)
{
const std::string bundleName = g_InfoParms1.bundleName;
const std::string permissionName = "ohos.permission.CAMERA";
auto& manager = PermissionRecordManager::GetInstance();
manager.bundleStartRecordMap_.clear();
ASSERT_EQ(RET_SUCCESS, manager.StartUsingPermission(bundleName, permissionName, CALLER_PID));
ASSERT_EQ(1, manager.bundleStartRecordMap_.size());
ASSERT_TRUE(manager.HasCallerInStartList(CALLER_PID));
ASSERT_EQ(PrivacyError::ERR_PERMISSION_ALREADY_START_USING,
manager.StartUsingPermission(bundleName, permissionName, CALLER_PID));
ASSERT_EQ(1, manager.bundleStartRecordMap_[bundleName].size());
ASSERT_EQ(RET_SUCCESS, manager.StopUsingPermission(bundleName, permissionName, CALLER_PID));
ASSERT_TRUE(manager.bundleStartRecordMap_.empty());
ASSERT_FALSE(manager.HasCallerInStartList(CALLER_PID));
}
/*
* @tc.name: StartUsingPermissionBundle002
* @tc.desc: StartUsingPermission bundle validates bundle and permission parameters
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(PermissionRecordManagerTest, StartUsingPermissionBundle002, TestSize.Level0)
{
auto& manager = PermissionRecordManager::GetInstance();
manager.bundleStartRecordMap_.clear();
ASSERT_EQ(PrivacyError::ERR_PARAM_INVALID, manager.StartUsingPermission("", "ohos.permission.CAMERA", CALLER_PID));
ASSERT_EQ(PrivacyError::ERR_PARAM_INVALID, manager.StartUsingPermission(g_InfoParms1.bundleName, "", CALLER_PID));
ASSERT_TRUE(manager.bundleStartRecordMap_.empty());
}
/*
* @tc.name: StartUsingPermissionBundle003
* @tc.desc: StartUsingPermission bundle returns ERR_PERMISSION_NOT_EXIST for unsupported permission
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(PermissionRecordManagerTest, StartUsingPermissionBundle003, TestSize.Level0)
{
auto& manager = PermissionRecordManager::GetInstance();
manager.bundleStartRecordMap_.clear();
ASSERT_EQ(PrivacyError::ERR_PERMISSION_NOT_EXIST,
manager.StartUsingPermission(g_InfoParms1.bundleName, "ohos.permission.TEST", CALLER_PID));
ASSERT_TRUE(manager.bundleStartRecordMap_.empty());
}
/*
* @tc.name: StartUsingPermissionBundle004
* @tc.desc: StartUsingPermission bundle returns EDM policy error when camera is muted by EDM policy
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(PermissionRecordManagerTest, StartUsingPermissionBundle004, TestSize.Level0)
{
auto& manager = PermissionRecordManager::GetInstance();
manager.bundleStartRecordMap_.clear();
char value[VALUE_MAX_LEN] = {0};
GetParameter(EDM_CAMERA_MUTE_KEY, "", value, VALUE_MAX_LEN - 1);
std::string muteState(value);
ASSERT_EQ(0, SetParameter(EDM_CAMERA_MUTE_KEY, "true"));
ASSERT_EQ(PrivacyError::ERR_EDM_POLICY_CHECK_FAILED,
manager.StartUsingPermission(g_InfoParms1.bundleName, "ohos.permission.CAMERA", CALLER_PID));
ASSERT_TRUE(manager.bundleStartRecordMap_.empty());
ASSERT_EQ(0, SetParameter(EDM_CAMERA_MUTE_KEY, muteState.c_str()));
}
/*
* @tc.name: StartUsingPermissionBundle005
* @tc.desc: StartUsingPermission bundle appends a new record when the bundle bucket already exists
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(PermissionRecordManagerTest, StartUsingPermissionBundle005, TestSize.Level0)
{
auto& manager = PermissionRecordManager::GetInstance();
manager.bundleStartRecordMap_.clear();
ASSERT_EQ(RET_SUCCESS, manager.StartUsingPermission(g_InfoParms1.bundleName, "ohos.permission.CAMERA", CALLER_PID));
ASSERT_EQ(1, manager.bundleStartRecordMap_.size());
ASSERT_EQ(1, manager.bundleStartRecordMap_[g_InfoParms1.bundleName].size());
ASSERT_EQ(RET_SUCCESS,
manager.StartUsingPermission(g_InfoParms1.bundleName, "ohos.permission.CAMERA", CALLER_PID2));
ASSERT_EQ(1, manager.bundleStartRecordMap_.size());
ASSERT_EQ(2, manager.bundleStartRecordMap_[g_InfoParms1.bundleName].size());
ASSERT_TRUE(manager.HasCallerInStartList(CALLER_PID));
ASSERT_TRUE(manager.HasCallerInStartList(CALLER_PID2));
ASSERT_EQ(RET_SUCCESS, manager.StopUsingPermission(g_InfoParms1.bundleName, "ohos.permission.CAMERA", CALLER_PID));
ASSERT_EQ(RET_SUCCESS, manager.StopUsingPermission(g_InfoParms1.bundleName, "ohos.permission.CAMERA", CALLER_PID2));
ASSERT_TRUE(manager.bundleStartRecordMap_.empty());
}
/*
* @tc.name: StopUsingPermissionBundle001
* @tc.desc: StopUsingPermission bundle returns ERR_PERMISSION_NOT_START_USING when bundle was never started
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(PermissionRecordManagerTest, StopUsingPermissionBundle001, TestSize.Level0)
{
auto& manager = PermissionRecordManager::GetInstance();
manager.bundleStartRecordMap_.clear();
ASSERT_EQ(PrivacyError::ERR_PERMISSION_NOT_START_USING,
manager.StopUsingPermission(g_InfoParms1.bundleName, "ohos.permission.CAMERA", CALLER_PID));
ASSERT_TRUE(manager.bundleStartRecordMap_.empty());
}
/*
* @tc.name: StopUsingPermissionBundle002
* @tc.desc: StopUsingPermission bundle validates bundle and permission parameters
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(PermissionRecordManagerTest, StopUsingPermissionBundle002, TestSize.Level0)
{
auto& manager = PermissionRecordManager::GetInstance();
manager.bundleStartRecordMap_.clear();
ASSERT_EQ(PrivacyError::ERR_PARAM_INVALID, manager.StopUsingPermission("", "ohos.permission.CAMERA", CALLER_PID));
ASSERT_EQ(PrivacyError::ERR_PARAM_INVALID, manager.StopUsingPermission(g_InfoParms1.bundleName, "", CALLER_PID));
ASSERT_TRUE(manager.bundleStartRecordMap_.empty());
}
/*
* @tc.name: StopUsingPermissionBundle003
* @tc.desc: StopUsingPermission bundle returns ERR_PERMISSION_NOT_EXIST for unsupported permission
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(PermissionRecordManagerTest, StopUsingPermissionBundle003, TestSize.Level0)
{
auto& manager = PermissionRecordManager::GetInstance();
manager.bundleStartRecordMap_.clear();
ASSERT_EQ(PrivacyError::ERR_PERMISSION_NOT_EXIST,
manager.StopUsingPermission(g_InfoParms1.bundleName, "ohos.permission.TEST", CALLER_PID));
ASSERT_TRUE(manager.bundleStartRecordMap_.empty());
}
/*
* @tc.name: StopUsingPermissionBundle004
* @tc.desc: StopUsingPermission bundle keeps record when permission does not match
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(PermissionRecordManagerTest, StopUsingPermissionBundle004, TestSize.Level0)
{
const std::string bundleName = g_InfoParms1.bundleName;
auto& manager = PermissionRecordManager::GetInstance();
manager.bundleStartRecordMap_.clear();
ASSERT_EQ(RET_SUCCESS, manager.StartUsingPermission(bundleName, "ohos.permission.CAMERA", CALLER_PID));
ASSERT_EQ(PrivacyError::ERR_PERMISSION_NOT_START_USING,
manager.StopUsingPermission(bundleName, "ohos.permission.MICROPHONE", CALLER_PID));
ASSERT_EQ(1, manager.bundleStartRecordMap_.size());
ASSERT_EQ(1, manager.bundleStartRecordMap_[bundleName].size());
ASSERT_TRUE(manager.HasCallerInStartList(CALLER_PID));
ASSERT_EQ(RET_SUCCESS, manager.StopUsingPermission(bundleName, "ohos.permission.CAMERA", CALLER_PID));
ASSERT_TRUE(manager.bundleStartRecordMap_.empty());
ASSERT_FALSE(manager.HasCallerInStartList(CALLER_PID));
}
/*
* @tc.name: StopUsingPermissionBundle005
* @tc.desc: StopUsingPermission bundle retains other caller records in the same bundle bucket
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(PermissionRecordManagerTest, StopUsingPermissionBundle005, TestSize.Level0)
{
const std::string bundleName = g_InfoParms1.bundleName;
const std::string permissionName = "ohos.permission.CAMERA";
auto& manager = PermissionRecordManager::GetInstance();
manager.bundleStartRecordMap_.clear();
ASSERT_EQ(RET_SUCCESS, manager.StartUsingPermission(bundleName, permissionName, CALLER_PID));
ASSERT_EQ(RET_SUCCESS, manager.StartUsingPermission(bundleName, permissionName, CALLER_PID2));
ASSERT_EQ(2, manager.bundleStartRecordMap_[bundleName].size());
ASSERT_TRUE(manager.HasCallerInStartList(CALLER_PID));
ASSERT_TRUE(manager.HasCallerInStartList(CALLER_PID2));
ASSERT_EQ(RET_SUCCESS, manager.StopUsingPermission(bundleName, permissionName, CALLER_PID));
ASSERT_EQ(1, manager.bundleStartRecordMap_.size());
ASSERT_EQ(1, manager.bundleStartRecordMap_[bundleName].size());
ASSERT_FALSE(manager.HasCallerInStartList(CALLER_PID));
ASSERT_TRUE(manager.HasCallerInStartList(CALLER_PID2));
ASSERT_EQ(RET_SUCCESS, manager.StopUsingPermission(bundleName, permissionName, CALLER_PID2));
ASSERT_TRUE(manager.bundleStartRecordMap_.empty());
ASSERT_FALSE(manager.HasCallerInStartList(CALLER_PID2));
}
/*
* @tc.name: CallerPidCleanup001
* @tc.desc: RemoveRecordFromStartListByCallerPid clears bundle records for the specified caller only
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(PermissionRecordManagerTest, CallerPidCleanup001, TestSize.Level0)
{
const std::string permissionName = "ohos.permission.CAMERA";
auto& manager = PermissionRecordManager::GetInstance();
manager.bundleStartRecordMap_.clear();
ASSERT_EQ(RET_SUCCESS, manager.StartUsingPermission(g_InfoParms1.bundleName, permissionName, CALLER_PID));
ASSERT_EQ(RET_SUCCESS, manager.StartUsingPermission(g_InfoParms1.bundleName, permissionName, CALLER_PID2));
ASSERT_EQ(RET_SUCCESS, manager.StartUsingPermission("ohos.privacy_test.bundleB", permissionName, CALLER_PID));
ASSERT_TRUE(manager.HasCallerInStartList(CALLER_PID));
ASSERT_TRUE(manager.HasCallerInStartList(CALLER_PID2));
manager.RemoveRecordFromStartListByCallerPid(CALLER_PID);
ASSERT_FALSE(manager.HasCallerInStartList(CALLER_PID));
ASSERT_TRUE(manager.HasCallerInStartList(CALLER_PID2));
ASSERT_EQ(1, manager.bundleStartRecordMap_.size());
ASSERT_EQ(1, manager.bundleStartRecordMap_[g_InfoParms1.bundleName].size());
ASSERT_EQ(RET_SUCCESS, manager.StopUsingPermission(g_InfoParms1.bundleName, permissionName, CALLER_PID2));
ASSERT_TRUE(manager.bundleStartRecordMap_.empty());
}
#endif
/*
* @tc.name: AddPermissionUsedRecordTest001
* @tc.desc: AddPermissionUsedRecord function test
@@ -1829,7 +2071,7 @@ HWTEST_F(PermissionRecordManagerTest, AddPermissionUsedRecordTest004, TestSize.L
sptr<PermActiveStatusChangeCallback> callback = new (std::nothrow) PermActiveStatusChangeCallback();
ASSERT_NE(nullptr, callback);
ASSERT_EQ(RET_SUCCESS, PermissionRecordManager::GetInstance().RegisterPermActiveStatusCallback(
GetSelfTokenID(), permList, callback->AsObject()));
GetSelfTokenID(), permList, callback->AsObject(), static_cast<int32_t>(CallbackRegisterType::TOKEN_ONLY)));
AddPermParamInfo info;
info.tokenId = tokenId;
@@ -1868,7 +2110,7 @@ HWTEST_F(PermissionRecordManagerTest, AddPermissionUsedRecordTest005, TestSize.L
sptr<PermActiveStatusChangeCallback> callback = new (std::nothrow) PermActiveStatusChangeCallback();
ASSERT_NE(nullptr, callback);
ASSERT_EQ(RET_SUCCESS, PermissionRecordManager::GetInstance().RegisterPermActiveStatusCallback(
GetSelfTokenID(), permList, callback->AsObject()));
GetSelfTokenID(), permList, callback->AsObject(), static_cast<int32_t>(CallbackRegisterType::TOKEN_ONLY)));
AddPermParamInfo info;
info.tokenId = tokenId;
@@ -1961,40 +2203,11 @@ HWTEST_F(PermissionRecordManagerTest, CheckPermissionInUse004, TestSize.Level1)
/**
* @tc.name: CheckPermissionInUse005
* @tc.desc: Test CheckPermissionInUse with empty permission name.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(PermissionRecordManagerTest, CheckPermissionInUse005, TestSize.Level1)
{
// Empty permission name should return error code
bool isUsing = false;
EXPECT_EQ(PrivacyError::ERR_PARAM_INVALID,
PermissionRecordManager::GetInstance().CheckPermissionInUse("", isUsing));
}
/**
* @tc.name: CheckPermissionInUse006
* @tc.desc: Test CheckPermissionInUse with permission name exceeding 256 characters.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(PermissionRecordManagerTest, CheckPermissionInUse006, TestSize.Level1)
{
// Permission name exceeding 256 characters should return error code
std::string longPermissionName(257, 'a'); // 257 characters, exceeds MAX_PERMISSION_NAME_LENGTH (256)
bool isUsing = false;
EXPECT_EQ(PrivacyError::ERR_PARAM_INVALID, PermissionRecordManager::GetInstance().CheckPermissionInUse(
longPermissionName, isUsing));
}
/**
* @tc.name: CheckPermissionInUse007
* @tc.desc: Test CheckPermissionInUse with multiple permissions.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(PermissionRecordManagerTest, CheckPermissionInUse007, TestSize.Level1)
HWTEST_F(PermissionRecordManagerTest, CheckPermissionInUse005, TestSize.Level1)
{
// Get HAP token from bundle
AccessTokenIDEx tokenIdEx = PrivacyTestCommon::GetHapTokenIdFromBundle(g_InfoParms1.userID,
@@ -2029,6 +2242,55 @@ HWTEST_F(PermissionRecordManagerTest, CheckPermissionInUse007, TestSize.Level1)
tokenId, PID, "ohos.permission.CAMERA", CALLER_PID));
}
/**
* @tc.name: CheckPermissionInUse006
* @tc.desc: Test CheckPermissionInUse with target permission not started while another permission is in use.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(PermissionRecordManagerTest, CheckPermissionInUse006, TestSize.Level1)
{
AccessTokenIDEx tokenIdEx = PrivacyTestCommon::GetHapTokenIdFromBundle(g_InfoParms1.userID,
g_InfoParms1.bundleName, g_InfoParms1.instIndex);
AccessTokenID tokenId = tokenIdEx.tokenIdExStruct.tokenID;
ASSERT_NE(INVALID_TOKENID, tokenId);
ASSERT_EQ(RET_SUCCESS, PermissionRecordManager::GetInstance().StartUsingPermission(
MakeInfo(tokenId, PID, "ohos.permission.CAMERA"), CALLER_PID));
bool isUsing = true;
EXPECT_EQ(RET_SUCCESS,
PermissionRecordManager::GetInstance().CheckPermissionInUse("ohos.permission.MICROPHONE", isUsing));
EXPECT_FALSE(isUsing);
ASSERT_EQ(RET_SUCCESS, PermissionRecordManager::GetInstance().StopUsingPermission(
tokenId, PID, "ohos.permission.CAMERA", CALLER_PID));
}
#ifdef PRIVACY_BUNDLE_START_STOP_ENABLE
/**
* @tc.name: CheckPermissionInUse007
* @tc.desc: Test CheckPermissionInUse with bundle start and stop.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(PermissionRecordManagerTest, CheckPermissionInUse007, TestSize.Level1)
{
const std::string bundleName = "ohos.permission.record.bundle";
ASSERT_EQ(RET_SUCCESS,
PermissionRecordManager::GetInstance().StartUsingPermission(bundleName, "ohos.permission.CAMERA", CALLER_PID));
bool isUsing = false;
EXPECT_EQ(RET_SUCCESS,
PermissionRecordManager::GetInstance().CheckPermissionInUse("ohos.permission.CAMERA", isUsing));
EXPECT_TRUE(isUsing);
ASSERT_EQ(RET_SUCCESS,
PermissionRecordManager::GetInstance().StopUsingPermission(bundleName, "ohos.permission.CAMERA", CALLER_PID));
}
#endif
/**
* @tc.name: CheckPermissionInUse008
* @tc.desc: Test CheckPermissionInUse after removing permission record.
@@ -2109,6 +2371,37 @@ HWTEST_F(PermissionRecordManagerTest, CheckPermissionInUse009, TestSize.Level1)
tokenId, PID, "ohos.permission.CAMERA", CALLER_PID));
}
#ifdef REMOTE_PRIVACY_ENABLE
/**
* @tc.name: CheckPermissionInUse010
* @tc.desc: Test CheckPermissionInUse with remote permission start and stop.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(PermissionRecordManagerTest, CheckPermissionInUse010, TestSize.Level1)
{
RemotePermissionUsedInfo info;
info.permissionName = "ohos.permission.CAMERA";
info.remoteDeviceId = "ididid";
info.remoteDeviceName = "namename";
ASSERT_EQ(RET_SUCCESS, PermissionRecordManager::GetInstance().StartRemoteUsingPermission(info, CALLER_PID));
bool isUsing = false;
EXPECT_EQ(RET_SUCCESS,
PermissionRecordManager::GetInstance().CheckPermissionInUse("ohos.permission.CAMERA", isUsing));
EXPECT_TRUE(isUsing);
ASSERT_EQ(RET_SUCCESS, PermissionRecordManager::GetInstance().StopRemoteUsingPermission(
info.remoteDeviceId, info.remoteDeviceName, info.permissionName, CALLER_PID));
isUsing = false;
EXPECT_EQ(RET_SUCCESS,
PermissionRecordManager::GetInstance().CheckPermissionInUse("ohos.permission.CAMERA", isUsing));
EXPECT_FALSE(isUsing);
}
#endif
#ifdef MAX_COUNT_TEST
class DisablePolicyChangeCallbackTest : public DisablePolicyChangeCallback {
public:
@@ -15,15 +15,18 @@
#include <gtest/gtest.h>
#include <memory>
#include <unistd.h>
#include "accesstoken_kit.h"
#include "constant.h"
#include "iprivacy_manager.h"
#include "on_permission_used_record_callback_stub.h"
#define private public
#include "proxy_death_handler.h"
#include "permission_record_manager.h"
#include "privacy_manager_service.h"
#undef private
#include "parameter.h"
#include "perm_active_status_change_callback_stub.h"
#include "perm_active_status_change_callback.h"
#include "privacy_error.h"
@@ -834,6 +837,246 @@ HWTEST_F(PrivacyManagerServiceTest, StartUsingPermissionInner003, TestSize.Level
ASSERT_EQ(PrivacyError::ERR_PERMISSION_DENIED, privacyManagerService_->StartUsingPermission(parcel, nullptr));
}
#ifdef PRIVACY_BUNDLE_START_STOP_ENABLE
/**
* @tc.name: BundleUsingServiceTest001
* @tc.desc: Verify bundle start enters business branch for native caller.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(PrivacyManagerServiceTest, BundleUsingServiceTest001, TestSize.Level0)
{
MockNativeToken mock("privacy_service");
int32_t ret = privacyManagerService_->StartUsingPermission(
"BundleUsingServiceTest001", CAMERA_PERMISSION_NAME, nullptr);
EXPECT_NE(PrivacyError::ERR_NOT_SYSTEM_APP, ret);
EXPECT_NE(PrivacyError::ERR_PERMISSION_DENIED, ret);
ASSERT_EQ(RET_SUCCESS, privacyManagerService_->StopUsingPermission(
"BundleUsingServiceTest001", CAMERA_PERMISSION_NAME));
}
/**
* @tc.name: BundleUsingServiceTest002
* @tc.desc: Verify bundle start returns ERR_NOT_SYSTEM_APP for normal hap caller.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(PrivacyManagerServiceTest, BundleUsingServiceTest002, TestSize.Level0)
{
std::vector<std::string> reqPerm;
MockHapToken mock("BundleUsingServiceTest002", reqPerm, false);
ASSERT_EQ(PrivacyError::ERR_NOT_SYSTEM_APP, privacyManagerService_->StartUsingPermission(
"BundleUsingServiceTest002", CAMERA_PERMISSION_NAME, nullptr));
}
/**
* @tc.name: BundleUsingServiceTest003
* @tc.desc: Verify bundle start returns ERR_PERMISSION_DENIED without permission.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(PrivacyManagerServiceTest, BundleUsingServiceTest003, TestSize.Level0)
{
std::vector<std::string> reqPerm;
MockHapToken mock("BundleUsingServiceTest003", reqPerm, true);
ASSERT_EQ(PrivacyError::ERR_PERMISSION_DENIED, privacyManagerService_->StartUsingPermission(
"BundleUsingServiceTest003", CAMERA_PERMISSION_NAME, nullptr));
}
/**
* @tc.name: BundleUsingServiceTest004
* @tc.desc: Verify bundle start succeeds for system hap with PERMISSION_USED_STATS.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(PrivacyManagerServiceTest, BundleUsingServiceTest004, TestSize.Level0)
{
std::vector<std::string> reqPerm = {"ohos.permission.PERMISSION_USED_STATS"};
MockHapToken mock("BundleUsingServiceTest004", reqPerm, true);
ASSERT_EQ(RET_SUCCESS, privacyManagerService_->StartUsingPermission(
"BundleUsingServiceTest004", CAMERA_PERMISSION_NAME, nullptr));
ASSERT_EQ(RET_SUCCESS, privacyManagerService_->StopUsingPermission(
"BundleUsingServiceTest004", CAMERA_PERMISSION_NAME));
}
/**
* @tc.name: BundleUsingServiceTest005
* @tc.desc: Verify bundle stop enters business branch for native caller.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(PrivacyManagerServiceTest, BundleUsingServiceTest005, TestSize.Level0)
{
MockNativeToken mock("privacy_service");
int32_t ret = privacyManagerService_->StopUsingPermission(
"BundleUsingServiceTest005", CAMERA_PERMISSION_NAME);
EXPECT_NE(PrivacyError::ERR_NOT_SYSTEM_APP, ret);
EXPECT_NE(PrivacyError::ERR_PERMISSION_DENIED, ret);
}
/**
* @tc.name: BundleUsingServiceTest006
* @tc.desc: Verify bundle stop returns ERR_NOT_SYSTEM_APP for normal hap caller.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(PrivacyManagerServiceTest, BundleUsingServiceTest006, TestSize.Level0)
{
std::vector<std::string> reqPerm;
MockHapToken mock("BundleUsingServiceTest006", reqPerm, false);
ASSERT_EQ(PrivacyError::ERR_NOT_SYSTEM_APP, privacyManagerService_->StopUsingPermission(
"BundleUsingServiceTest006", CAMERA_PERMISSION_NAME));
}
/**
* @tc.name: BundleUsingServiceTest007
* @tc.desc: Verify bundle stop returns ERR_PERMISSION_DENIED without permission.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(PrivacyManagerServiceTest, BundleUsingServiceTest007, TestSize.Level0)
{
std::vector<std::string> reqPerm;
MockHapToken mock("BundleUsingServiceTest007", reqPerm, true);
ASSERT_EQ(PrivacyError::ERR_PERMISSION_DENIED, privacyManagerService_->StopUsingPermission(
"BundleUsingServiceTest007", CAMERA_PERMISSION_NAME));
}
/**
* @tc.name: BundleUsingServiceTest008
* @tc.desc: Verify bundle stop succeeds for system hap with PERMISSION_USED_STATS.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(PrivacyManagerServiceTest, BundleUsingServiceTest008, TestSize.Level0)
{
std::vector<std::string> reqPerm = {"ohos.permission.PERMISSION_USED_STATS"};
MockHapToken mock("BundleUsingServiceTest008", reqPerm, true);
ASSERT_EQ(RET_SUCCESS, privacyManagerService_->StartUsingPermission(
"BundleUsingServiceTest008", CAMERA_PERMISSION_NAME, nullptr));
ASSERT_EQ(RET_SUCCESS, privacyManagerService_->StopUsingPermission(
"BundleUsingServiceTest008", CAMERA_PERMISSION_NAME));
}
/**
* @tc.name: BundleUsingServiceTest009
* @tc.desc: Verify caller remains in bundle start list when another bundle record is still active after stop.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(PrivacyManagerServiceTest, BundleUsingServiceTest009, TestSize.Level0)
{
std::vector<std::string> reqPerm = {"ohos.permission.PERMISSION_USED_STATS"};
MockHapToken mock("BundleUsingServiceTest009", reqPerm, true);
auto& manager = PermissionRecordManager::GetInstance();
int32_t callerPid = getpid();
manager.bundleStartRecordMap_.clear();
ASSERT_EQ(RET_SUCCESS, privacyManagerService_->StartUsingPermission(
"BundleUsingServiceTest009", CAMERA_PERMISSION_NAME, nullptr));
ASSERT_EQ(RET_SUCCESS, privacyManagerService_->StartUsingPermission(
g_InfoParms1.bundleName, CAMERA_PERMISSION_NAME, nullptr));
ASSERT_TRUE(manager.HasCallerInStartList(callerPid));
ASSERT_EQ(RET_SUCCESS, privacyManagerService_->StopUsingPermission(
"BundleUsingServiceTest009", CAMERA_PERMISSION_NAME));
ASSERT_TRUE(manager.HasCallerInStartList(callerPid));
ASSERT_EQ(RET_SUCCESS, privacyManagerService_->StopUsingPermission(
g_InfoParms1.bundleName, CAMERA_PERMISSION_NAME));
ASSERT_FALSE(manager.HasCallerInStartList(callerPid));
}
/**
* @tc.name: BundleUsingServiceTest010
* @tc.desc: Verify stopping the last bundle record releases the death proxy for the caller.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(PrivacyManagerServiceTest, BundleUsingServiceTest010, TestSize.Level0)
{
std::vector<std::string> reqPerm = {"ohos.permission.PERMISSION_USED_STATS"};
MockHapToken mock("BundleUsingServiceTest010", reqPerm, true);
auto& manager = PermissionRecordManager::GetInstance();
int32_t callerPid = getpid();
manager.bundleStartRecordMap_.clear();
sptr<ProxyDeathCallBackStub> callback = new (std::nothrow) ProxyDeathCallBackStub();
ASSERT_NE(nullptr, callback);
auto handler = privacyManagerService_->GetProxyDeathHandler();
ASSERT_NE(nullptr, handler);
handler->proxyStubAndRecipientMap_.clear();
ASSERT_EQ(RET_SUCCESS, privacyManagerService_->StartUsingPermission(
"BundleUsingServiceTest010", CAMERA_PERMISSION_NAME, callback->AsObject()));
ASSERT_TRUE(manager.HasCallerInStartList(callerPid));
ASSERT_EQ(1, static_cast<int32_t>(handler->proxyStubAndRecipientMap_.size()));
ASSERT_EQ(RET_SUCCESS, privacyManagerService_->StopUsingPermission(
"BundleUsingServiceTest010", CAMERA_PERMISSION_NAME));
ASSERT_FALSE(manager.HasCallerInStartList(callerPid));
ASSERT_TRUE(handler->proxyStubAndRecipientMap_.empty());
}
/**
* @tc.name: BundleUsingServiceTest011
* @tc.desc: Verify stopping bundle record does not release death proxy while token record of the same caller remains.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(PrivacyManagerServiceTest, BundleUsingServiceTest011, TestSize.Level0)
{
std::vector<std::string> reqPerm = {"ohos.permission.PERMISSION_USED_STATS"};
MockHapToken mock("BundleUsingServiceTest011", reqPerm, true);
auto& manager = PermissionRecordManager::GetInstance();
int32_t callerPid = getpid();
manager.bundleStartRecordMap_.clear();
AccessTokenIDEx tokenIdEx = PrivacyTestCommon::GetHapTokenIdFromBundle(
g_InfoParms1.userID, g_InfoParms1.bundleName, g_InfoParms1.instIndex);
ASSERT_NE(INVALID_TOKENID, tokenIdEx.tokenIdExStruct.tokenID);
sptr<ProxyDeathCallBackStub> callback = new (std::nothrow) ProxyDeathCallBackStub();
ASSERT_NE(nullptr, callback);
auto handler = privacyManagerService_->GetProxyDeathHandler();
ASSERT_NE(nullptr, handler);
handler->proxyStubAndRecipientMap_.clear();
PermissionUsedTypeInfoParcel parcel;
parcel.info.tokenId = tokenIdEx.tokenIdExStruct.tokenID;
parcel.info.pid = -1;
parcel.info.permissionName = CAMERA_PERMISSION_NAME;
parcel.info.type = PermissionUsedType::NORMAL_TYPE;
ASSERT_EQ(RET_SUCCESS, privacyManagerService_->StartUsingPermission(parcel, callback->AsObject()));
ASSERT_EQ(RET_SUCCESS, privacyManagerService_->StartUsingPermission(
"BundleUsingServiceTest011", CAMERA_PERMISSION_NAME, callback->AsObject()));
ASSERT_EQ(1, static_cast<int32_t>(handler->proxyStubAndRecipientMap_.size()));
ASSERT_TRUE(manager.HasCallerInStartList(callerPid));
ASSERT_EQ(RET_SUCCESS, privacyManagerService_->StopUsingPermission(
"BundleUsingServiceTest011", CAMERA_PERMISSION_NAME));
ASSERT_EQ(1, static_cast<int32_t>(handler->proxyStubAndRecipientMap_.size()));
ASSERT_TRUE(manager.HasCallerInStartList(callerPid));
ASSERT_EQ(RET_SUCCESS, privacyManagerService_->StopUsingPermission(
tokenIdEx.tokenIdExStruct.tokenID, -1, CAMERA_PERMISSION_NAME));
ASSERT_FALSE(manager.HasCallerInStartList(callerPid));
ASSERT_TRUE(handler->proxyStubAndRecipientMap_.empty());
}
#endif
/**
* @tc.name: StartUsingPermissionCallbackInner001
* @tc.desc: StartUsingPermissionCallbackInner test.
@@ -1150,7 +1393,14 @@ HWTEST_F(PrivacyManagerServiceTest, RegisterPermActiveStatusCallbackInner001, Te
// permList size oversize
ASSERT_EQ(PrivacyError::ERR_OVERSIZE,
privacyManagerService_->RegisterPermActiveStatusCallback(permList, nullptr));
privacyManagerService_->RegisterPermActiveStatusCallback(
permList, nullptr, static_cast<int32_t>(CallbackRegisterType::TOKEN_ONLY)));
permList.clear();
ASSERT_EQ(PrivacyError::ERR_PARAM_INVALID,
privacyManagerService_->RegisterPermActiveStatusCallback(permList, nullptr, -1));
ASSERT_EQ(PrivacyError::ERR_PARAM_INVALID,
privacyManagerService_->RegisterPermActiveStatusCallback(permList, nullptr, 2));
}
/**
@@ -1168,7 +1418,8 @@ HWTEST_F(PrivacyManagerServiceTest, RegisterPermActiveStatusCallbackInner002, Te
// callingTokenID is normal hap without need permission
ASSERT_EQ(PrivacyError::ERR_NOT_SYSTEM_APP,
privacyManagerService_->RegisterPermActiveStatusCallback(permList, nullptr));
privacyManagerService_->RegisterPermActiveStatusCallback(
permList, nullptr, static_cast<int32_t>(CallbackRegisterType::TOKEN_ONLY)));
}
/**
@@ -1186,7 +1437,8 @@ HWTEST_F(PrivacyManagerServiceTest, RegisterPermActiveStatusCallbackInner003, Te
// callingTokenID is system hap without need permission
ASSERT_EQ(PrivacyError::ERR_PERMISSION_DENIED,
privacyManagerService_->RegisterPermActiveStatusCallback(permList, nullptr));
privacyManagerService_->RegisterPermActiveStatusCallback(
permList, nullptr, static_cast<int32_t>(CallbackRegisterType::TOKEN_ONLY)));
}
/**
@@ -1200,7 +1452,13 @@ HWTEST_F(PrivacyManagerServiceTest, RegisterPermActiveStatusCallbackInner004, Te
std::vector<std::string> permList;
// systemapp with need permission
int32_t ret = privacyManagerService_->RegisterPermActiveStatusCallback(permList, nullptr);
int32_t ret = privacyManagerService_->RegisterPermActiveStatusCallback(
permList, nullptr, static_cast<int32_t>(CallbackRegisterType::TOKEN_ONLY));
EXPECT_NE(PrivacyError::ERR_NOT_SYSTEM_APP, ret);
EXPECT_NE(PrivacyError::ERR_PERMISSION_DENIED, ret);
ret = privacyManagerService_->RegisterPermActiveStatusCallback(
permList, nullptr, static_cast<int32_t>(CallbackRegisterType::ALL));
EXPECT_NE(PrivacyError::ERR_NOT_SYSTEM_APP, ret);
EXPECT_NE(PrivacyError::ERR_PERMISSION_DENIED, ret);
}
@@ -1607,7 +1865,7 @@ HWTEST_F(PrivacyManagerServiceTest, CheckPermissionInUse004, TestSize.Level0)
/**
* @tc.name: CheckPermissionInUse005
* @tc.desc: Test CheckPermissionInUse after stopping permission use.
* @tc.desc: Test CheckPermissionInUse with permission name exceeding 256 characters.
* @tc.type: FUNC
* @tc.require:
*/
@@ -1617,6 +1875,24 @@ HWTEST_F(PrivacyManagerServiceTest, CheckPermissionInUse005, TestSize.Level0)
reqPerm.emplace_back("ohos.permission.PERMISSION_USED_STATS");
MockHapToken mock("CheckPermissionInUse005", reqPerm, true); // set self tokenID to system app
std::string longPermissionName(257, 'a');
bool isUsing = false;
ASSERT_EQ(PrivacyError::ERR_PARAM_INVALID,
privacyManagerService_->CheckPermissionInUse(longPermissionName, isUsing));
}
/**
* @tc.name: CheckPermissionInUse006
* @tc.desc: Test CheckPermissionInUse after stopping permission use.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(PrivacyManagerServiceTest, CheckPermissionInUse006, TestSize.Level0)
{
std::vector<std::string> reqPerm;
reqPerm.emplace_back("ohos.permission.PERMISSION_USED_STATS");
MockHapToken mock("CheckPermissionInUse006", reqPerm, true); // set self tokenID to system app
// Start using permission
PermissionUsedTypeInfoParcel parcel;
AccessTokenID tokenID = 123; // use local tokenID variable
@@ -1639,16 +1915,16 @@ HWTEST_F(PrivacyManagerServiceTest, CheckPermissionInUse005, TestSize.Level0)
}
/**
* @tc.name: CheckPermissionInUse006
* @tc.name: CheckPermissionInUse007
* @tc.desc: Test CheckPermissionInUse caller is not system app.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(PrivacyManagerServiceTest, CheckPermissionInUse006, TestSize.Level0)
HWTEST_F(PrivacyManagerServiceTest, CheckPermissionInUse007, TestSize.Level0)
{
std::vector<std::string> reqPerm;
reqPerm.emplace_back("ohos.permission.PERMISSION_USED_STATS");
MockHapToken mock("CheckPermissionInUse006", reqPerm, false);
MockHapToken mock("CheckPermissionInUse007", reqPerm, false);
bool isUsing = false;
ASSERT_EQ(PrivacyError::ERR_NOT_SYSTEM_APP,
@@ -1656,15 +1932,15 @@ HWTEST_F(PrivacyManagerServiceTest, CheckPermissionInUse006, TestSize.Level0)
}
/**
* @tc.name: CheckPermissionInUse007
* @tc.name: CheckPermissionInUse008
* @tc.desc: Test CheckPermissionInUse caller is system app without PERMISSION_USED_STATS permission.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(PrivacyManagerServiceTest, CheckPermissionInUse007, TestSize.Level0)
HWTEST_F(PrivacyManagerServiceTest, CheckPermissionInUse008, TestSize.Level0)
{
std::vector<std::string> reqPerm; // empty permission list - no PERMISSION_USED_STATS
MockHapToken mock("CheckPermissionInUse007", reqPerm, true); // isSystemApp = true
MockHapToken mock("CheckPermissionInUse008", reqPerm, true); // isSystemApp = true
bool isUsing = false;
ASSERT_EQ(PrivacyError::ERR_PERMISSION_DENIED,
+1
View File
@@ -31,6 +31,7 @@ group("fuzztest") {
"setpermissionusedrecordtogglestatus_fuzzer:SetPermissionUsedRecordToggleStatusFuzzTest",
"startusingpermission001_fuzzer:StartUsingPermission001FuzzTest",
"startusingpermission_fuzzer:StartUsingPermissionFuzzTest",
"startusingpermissionbundle_fuzzer:StartUsingPermissionBundleFuzzTest",
"stopusingpermission_fuzzer:StopUsingPermissionFuzzTest",
"unregisterpermactivestatuscallback_fuzzer:UnRegisterPermActiveStatusCallbackFuzzTest",
]
@@ -0,0 +1,36 @@
# Copyright (c) 2026 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.
import("//base/security/access_token/access_token.gni")
import("//build/config/features.gni")
import("//build/test.gni")
import("../privacy_fuzzer.gni")
ohos_fuzztest("StartUsingPermissionBundleFuzzTest") {
module_out_path = module_output_path_interface_privacy
fuzz_config_file = "."
include_dirs = privacy_fuzzer_include_dirs +
[ "${access_token_path}/frameworks/common/include" ]
cflags = privacy_fuzzer_cflags
sources = [ "startusingpermissionbundle_fuzzer.cpp" ]
deps = [
"${access_token_path}/frameworks/common:accesstoken_common_cxx",
"${access_token_path}/interfaces/innerkits/accesstoken:libaccesstoken_sdk",
"${access_token_path}/interfaces/innerkits/privacy:libprivacy_sdk",
]
configs = privacy_fuzzer_configs
external_deps = privacy_fuzzer_external_deps
}
@@ -0,0 +1,14 @@
# Copyright (c) 2026 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.
FUZZ
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2026 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.
-->
<fuzz_config>
<fuzztest>
<!-- maximum length of a test input -->
<max_len>1000</max_len>
<!-- maximum total time in seconds to run the fuzzer -->
<max_total_time>300</max_total_time>
<!-- memory usage limit in Mb -->
<rss_limit_mb>4096</rss_limit_mb>
</fuzztest>
</fuzz_config>
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2026 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 "startusingpermissionbundle_fuzzer.h"
#include <string>
#include "accesstoken_fuzzdata.h"
#include "fuzzer/FuzzedDataProvider.h"
#undef private
#include "privacy_kit.h"
using namespace OHOS::Security::AccessToken;
namespace OHOS {
bool StartUsingPermissionBundleFuzzTest(const uint8_t* data, size_t size)
{
if ((data == nullptr) || (size == 0)) {
return false;
}
FuzzedDataProvider provider(data, size);
return PrivacyKit::StartUsingPermission(
provider.ConsumeRandomLengthString(), ConsumePermissionName(provider)) == 0;
}
} // namespace OHOS
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
OHOS::StartUsingPermissionBundleFuzzTest(data, size);
return 0;
}
@@ -0,0 +1,22 @@
/*
* Copyright (c) 2026 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 START_USING_PERMISSION_BUNDLE_FUZZER_H
#define START_USING_PERMISSION_BUNDLE_FUZZER_H
#include <cstddef>
#include <cstdint>
#endif // START_USING_PERMISSION_BUNDLE_FUZZER_H
@@ -0,0 +1,36 @@
# Copyright (c) 2026 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.
import("//base/security/access_token/access_token.gni")
import("//build/config/features.gni")
import("//build/test.gni")
import("../privacy_fuzzer.gni")
ohos_fuzztest("StopUsingPermissionBundleFuzzTest") {
module_out_path = module_output_path_interface_privacy
fuzz_config_file = "."
include_dirs = privacy_fuzzer_include_dirs +
[ "${access_token_path}/frameworks/common/include" ]
cflags = privacy_fuzzer_cflags
sources = [ "stopusingpermissionbundle_fuzzer.cpp" ]
deps = [
"${access_token_path}/frameworks/common:accesstoken_common_cxx",
"${access_token_path}/interfaces/innerkits/accesstoken:libaccesstoken_sdk",
"${access_token_path}/interfaces/innerkits/privacy:libprivacy_sdk",
]
configs = privacy_fuzzer_configs
external_deps = privacy_fuzzer_external_deps
}
@@ -0,0 +1,14 @@
# Copyright (c) 2026 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.
FUZZ
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2026 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.
-->
<fuzz_config>
<fuzztest>
<!-- maximum length of a test input -->
<max_len>1000</max_len>
<!-- maximum total time in seconds to run the fuzzer -->
<max_total_time>300</max_total_time>
<!-- memory usage limit in Mb -->
<rss_limit_mb>4096</rss_limit_mb>
</fuzztest>
</fuzz_config>
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2026 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 "stopusingpermissionbundle_fuzzer.h"
#include <string>
#include "accesstoken_fuzzdata.h"
#include "fuzzer/FuzzedDataProvider.h"
#undef private
#include "privacy_kit.h"
using namespace OHOS::Security::AccessToken;
namespace OHOS {
bool StopUsingPermissionBundleFuzzTest(const uint8_t* data, size_t size)
{
if ((data == nullptr) || (size == 0)) {
return false;
}
FuzzedDataProvider provider(data, size);
return PrivacyKit::StopUsingPermission(
provider.ConsumeRandomLengthString(), ConsumePermissionName(provider)) == 0;
}
} // namespace OHOS
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
OHOS::StopUsingPermissionBundleFuzzTest(data, size);
return 0;
}
@@ -0,0 +1,22 @@
/*
* Copyright (c) 2026 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 STOP_USING_PERMISSION_BUNDLE_FUZZER_H
#define STOP_USING_PERMISSION_BUNDLE_FUZZER_H
#include <cstddef>
#include <cstdint>
#endif // STOP_USING_PERMISSION_BUNDLE_FUZZER_H
+2
View File
@@ -32,7 +32,9 @@ group("fuzztest") {
"setmutepolicystub_fuzzer:SetMutePolicyStubFuzzTest",
"setpermissionusedrecordtogglestatusstub_fuzzer:SetPermissionUsedRecordToggleStatusStubFuzzTest",
"startusingpermissioncallbackstub_fuzzer:StartUsingPermissionCallbackStubFuzzTest",
"startusingpermissionbundlestub_fuzzer:StartUsingPermissionBundleStubFuzzTest",
"startusingpermissionstub_fuzzer:StartUsingPermissionStubFuzzTest",
"stopusingpermissionbundlestub_fuzzer:StopUsingPermissionBundleStubFuzzTest",
"stopusingpermissionstub_fuzzer:StopUsingPermissionStubFuzzTest",
"unregisterpermactivestatuscallbackstub_fuzzer:UnRegisterPermActiveStatusCallbackStubFuzzTest",
]
@@ -90,7 +90,7 @@ bool StartRemoteUsingPermissionStubFuzzTest(const uint8_t* data, size_t size)
FuzzedDataProvider provider(data, size);
std::string permissionName;
int32_t opCode = provider.ConsumeIntegral<int32_t>() % g_permSize;
Constant::TransferOpcodeToPermission(opCode, permissionName);
(void)Constant::TransferOpcodeToPermission(opCode, permissionName);
std::string remoteDeviceId = provider.ConsumeRandomLengthString();
std::string remoteDeviceName = provider.ConsumeRandomLengthString();
@@ -0,0 +1,36 @@
# Copyright (c) 2026 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.
import("//build/config/features.gni")
import("//build/test.gni")
import("../privacy_service_fuzz.gni")
ohos_fuzztest("StartUsingPermissionBundleStubFuzzTest") {
module_out_path = module_output_path_service_privacy
fuzz_config_file = "."
sources = [ "startusingpermissionbundlestub_fuzzer.cpp" ]
sources += [ "${access_token_path}/services/common/proxy_death/src/proxy_death_callback_stub.cpp" ]
sources += privacy_stub_fuzz_sources
include_dirs = privacy_stub_fuzz_include_dirs
deps = privacy_stub_fuzz_deps
configs = privacy_stub_fuzz_configs
external_deps = privacy_stub_fuzz_external_deps
cflags_cc = privacy_stub_fuzz_cflags_cc
cflags = privacy_stub_fuzz_cflags
}
@@ -0,0 +1,14 @@
# Copyright (c) 2026 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.
FUZZ
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2026 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.
-->
<fuzz_config>
<fuzztest>
<!-- maximum length of a test input -->
<max_len>1000</max_len>
<!-- maximum total time in seconds to run the fuzzer -->
<max_total_time>300</max_total_time>
<!-- memory usage limit in Mb -->
<rss_limit_mb>4096</rss_limit_mb>
</fuzztest>
</fuzz_config>
@@ -0,0 +1,69 @@
/*
* Copyright (c) 2026 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 "startusingpermissionbundlestub_fuzzer.h"
#include <string>
#include "accesstoken_fuzzdata.h"
#include "fuzzer/FuzzedDataProvider.h"
#include "iprivacy_manager.h"
#include "privacy_manager_service.h"
#include "proxy_death_callback_stub.h"
using namespace OHOS::Security::AccessToken;
namespace OHOS {
void StartUsingPermissionBundleStub(const std::string& bundleName, const std::string& permissionName)
{
MessageParcel data;
if (!data.WriteInterfaceToken(IPrivacyManager::GetDescriptor())) {
return;
}
auto anonyStub = sptr<ProxyDeathCallBackStub>::MakeSptr();
if (!data.WriteString(bundleName)) {
return;
}
if (!data.WriteString(permissionName)) {
return;
}
if (!data.WriteRemoteObject(anonyStub)) {
return;
}
MessageParcel reply;
MessageOption option(MessageOption::TF_SYNC);
DelayedSingleton<PrivacyManagerService>::GetInstance()->OnRemoteRequest(
static_cast<uint32_t>(IPrivacyManagerIpcCode::COMMAND_START_USING_PERMISSION),
data, reply, option);
}
bool StartUsingPermissionBundleStubFuzzTest(const uint8_t* data, size_t size)
{
if ((data == nullptr) || (size == 0)) {
return false;
}
FuzzedDataProvider provider(data, size);
StartUsingPermissionBundleStub(provider.ConsumeRandomLengthString(), ConsumePermissionName(provider));
return true;
}
} // namespace OHOS
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
OHOS::StartUsingPermissionBundleStubFuzzTest(data, size);
return 0;
}
@@ -0,0 +1,22 @@
/*
* Copyright (c) 2026 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 START_USING_PERMISSION_BUNDLE_STUB_FUZZER_H
#define START_USING_PERMISSION_BUNDLE_STUB_FUZZER_H
#include <cstddef>
#include <cstdint>
#endif // START_USING_PERMISSION_BUNDLE_STUB_FUZZER_H
@@ -118,7 +118,7 @@ bool StartUsingPermissionCallbackStubFuzzTest(const uint8_t* data, size_t size)
int32_t pid = provider.ConsumeIntegral<int32_t>();
std::string permissionName;
int32_t opCode = provider.ConsumeIntegral<int32_t>() % g_permSize;
Constant::TransferOpcodeToPermission(opCode, permissionName);
(void)Constant::TransferOpcodeToPermission(opCode, permissionName);
StartUsingPermissionCallbackStub(tokenID, pid, permissionName);
StopUsingPermissionStub(tokenID, pid, permissionName);
@@ -88,7 +88,7 @@ bool StartUsingPermissionStubFuzzTest(const uint8_t* data, size_t size)
int32_t pid = provider.ConsumeIntegral<int32_t>();
std::string permissionName;
int32_t opCode = provider.ConsumeIntegral<int32_t>() % g_permSize;
Constant::TransferOpcodeToPermission(opCode, permissionName);
(void)Constant::TransferOpcodeToPermission(opCode, permissionName);
StartUsingPermissionStub(tokenID, pid, permissionName);
StopUsingPermissionStub(tokenID, pid, permissionName);
@@ -0,0 +1,35 @@
# Copyright (c) 2026 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.
import("//build/config/features.gni")
import("//build/test.gni")
import("../privacy_service_fuzz.gni")
ohos_fuzztest("StopUsingPermissionBundleStubFuzzTest") {
module_out_path = module_output_path_service_privacy
fuzz_config_file = "."
sources = [ "stopusingpermissionbundlestub_fuzzer.cpp" ]
sources += privacy_stub_fuzz_sources
include_dirs = privacy_stub_fuzz_include_dirs
deps = privacy_stub_fuzz_deps
configs = privacy_stub_fuzz_configs
external_deps = privacy_stub_fuzz_external_deps
cflags_cc = privacy_stub_fuzz_cflags_cc
cflags = privacy_stub_fuzz_cflags
}
@@ -0,0 +1,14 @@
# Copyright (c) 2026 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.
FUZZ
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2026 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.
-->
<fuzz_config>
<fuzztest>
<!-- maximum length of a test input -->
<max_len>1000</max_len>
<!-- maximum total time in seconds to run the fuzzer -->
<max_total_time>300</max_total_time>
<!-- memory usage limit in Mb -->
<rss_limit_mb>4096</rss_limit_mb>
</fuzztest>
</fuzz_config>
@@ -0,0 +1,64 @@
/*
* Copyright (c) 2026 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 "stopusingpermissionbundlestub_fuzzer.h"
#include <string>
#include "accesstoken_fuzzdata.h"
#include "fuzzer/FuzzedDataProvider.h"
#include "iprivacy_manager.h"
#include "privacy_manager_service.h"
using namespace OHOS::Security::AccessToken;
namespace OHOS {
void StopUsingPermissionBundleStub(const std::string& bundleName, const std::string& permissionName)
{
MessageParcel data;
if (!data.WriteInterfaceToken(IPrivacyManager::GetDescriptor())) {
return;
}
if (!data.WriteString(bundleName)) {
return;
}
if (!data.WriteString(permissionName)) {
return;
}
MessageParcel reply;
MessageOption option(MessageOption::TF_SYNC);
DelayedSingleton<PrivacyManagerService>::GetInstance()->OnRemoteRequest(
static_cast<uint32_t>(IPrivacyManagerIpcCode::COMMAND_STOP_USING_PERMISSION),
data, reply, option);
}
bool StopUsingPermissionBundleStubFuzzTest(const uint8_t* data, size_t size)
{
if ((data == nullptr) || (size == 0)) {
return false;
}
FuzzedDataProvider provider(data, size);
StopUsingPermissionBundleStub(provider.ConsumeRandomLengthString(), ConsumePermissionName(provider));
return true;
}
} // namespace OHOS
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
OHOS::StopUsingPermissionBundleStubFuzzTest(data, size);
return 0;
}
@@ -0,0 +1,22 @@
/*
* Copyright (c) 2026 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 STOP_USING_PERMISSION_BUNDLE_STUB_FUZZER_H
#define STOP_USING_PERMISSION_BUNDLE_STUB_FUZZER_H
#include <cstddef>
#include <cstdint>
#endif // STOP_USING_PERMISSION_BUNDLE_STUB_FUZZER_H