* 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 "sensor_data_block_policy.h"
#include "sensor_errors.h"
#include "sensor_log.h"
#undef LOG_TAG
#define LOG_TAG "SensorDataBlockPolicy"
namespace OHOS {
namespace Sensors {
using namespace OHOS::HiviewDFX;
ErrCode SensorDataBlockPolicy::BlockSensorDataByPid(int32_t targetPid, const std::vector<int32_t> &sensorTypes,
int32_t clientPid)
{
CALL_LOG_ENTER;
if (targetPid <= 0 || clientPid <= 0) {
SEN_HILOGE("Invalid pid, targetPid:%{public}d, clientPid:%{public}d", targetPid, clientPid);
return PARAMETER_ERROR;
}
if (sensorTypes.empty()) {
SEN_HILOGE("SensorTypes is empty");
return PARAMETER_ERROR;
}
std::lock_guard<std::mutex> lock(blockPolicyMutex_);
auto targetIt = blockPolicies_.find(targetPid);
if (targetIt != blockPolicies_.end()) {
auto clientIt = targetIt->second.find(clientPid);
if (clientIt != targetIt->second.end()) {
for (const auto &sensorType : sensorTypes) {
clientIt->second.sensorTypes.insert(sensorType);
}
SEN_HILOGI("Update existing block policy for targetPid:%{public}d, clientPid:%{public}d",
targetPid, clientPid);
return ERR_OK;
}
}
BlockPolicy policy(targetPid, clientPid);
for (const auto &sensorType : sensorTypes) {
policy.sensorTypes.insert(sensorType);
}
blockPolicies_[targetPid][clientPid] = policy;
SEN_HILOGI("Add block policy for targetPid:%{public}d, clientPid:%{public}d, sensorCount:%{public}zu",
targetPid, clientPid, policy.sensorTypes.size());
return ERR_OK;
}
ErrCode SensorDataBlockPolicy::UnblockSensorDataByClient(int32_t clientPid, int32_t targetPid)
{
CALL_LOG_ENTER;
if (clientPid <= 0 || targetPid <= 0) {
SEN_HILOGE("Invalid clientPid:%{public}d or targetPid:%{public}d", clientPid, targetPid);
return PARAMETER_ERROR;
}
std::lock_guard<std::mutex> lock(blockPolicyMutex_);
auto targetIt = blockPolicies_.find(targetPid);
if (targetIt == blockPolicies_.end()) {
SEN_HILOGW("No block policy found for targetPid:%{public}d", targetPid);
return ERR_OK;
}
auto clientIt = targetIt->second.find(clientPid);
if (clientIt == targetIt->second.end()) {
SEN_HILOGW("No block policy found for clientPid:%{public}d", clientPid);
return ERR_OK;
}
targetIt->second.erase(clientIt);
SEN_HILOGI("Remove block policy for targetPid:%{public}d, clientPid:%{public}d",
targetPid, clientPid);
if (targetIt->second.empty()) {
blockPolicies_.erase(targetIt);
SEN_HILOGI("Remove targetPid:%{public}d as all client policies are cleared", targetPid);
}
return ERR_OK;
}
bool SensorDataBlockPolicy::IsSensorDataBlocked(int32_t targetPid, int32_t sensorType) const
{
std::lock_guard<std::mutex> lock(blockPolicyMutex_);
auto targetIt = blockPolicies_.find(targetPid);
if (targetIt == blockPolicies_.end()) {
return false;
}
for (const auto &clientEntry : targetIt->second) {
if (clientEntry.second.sensorTypes.find(sensorType) != clientEntry.second.sensorTypes.end()) {
return true;
}
}
return false;
}
void SensorDataBlockPolicy::ClearBlockPolicyByClient(int32_t clientPid)
{
CALL_LOG_ENTER;
std::lock_guard<std::mutex> lock(blockPolicyMutex_);
for (auto targetIt = blockPolicies_.begin(); targetIt != blockPolicies_.end();) {
targetIt->second.erase(clientPid);
if (targetIt->second.empty()) {
targetIt = blockPolicies_.erase(targetIt);
} else {
++targetIt;
}
}
SEN_HILOGI("Remove all block policies for clientPid:%{public}d", clientPid);
}
std::vector<int32_t> SensorDataBlockPolicy::GetBlockedSensorTypes(int32_t targetPid) const
{
std::vector<int32_t> blockedTypes;
std::lock_guard<std::mutex> lock(blockPolicyMutex_);
auto targetIt = blockPolicies_.find(targetPid);
if (targetIt == blockPolicies_.end()) {
return blockedTypes;
}
for (const auto &clientEntry : targetIt->second) {
for (const auto &sensorType : clientEntry.second.sensorTypes) {
blockedTypes.push_back(sensorType);
}
}
return blockedTypes;
}
void SensorDataBlockPolicy::ClearAllBlockPolicies()
{
CALL_LOG_ENTER;
std::lock_guard<std::mutex> lock(blockPolicyMutex_);
size_t count = blockPolicies_.size();
blockPolicies_.clear();
SEN_HILOGI("Cleared all block policies, count:%{public}zu", count);
}
std::string SensorDataBlockPolicy::DumpBlockPolicies() const
{
std::lock_guard<std::mutex> lock(blockPolicyMutex_);
std::string dumpInfo = "Sensor Data Block Policies:\n";
if (blockPolicies_.empty()) {
dumpInfo += " No active block policies\n";
return dumpInfo;
}
for (const auto &targetEntry : blockPolicies_) {
dumpInfo += " TargetPid: " + std::to_string(targetEntry.first) + "\n";
for (const auto &clientEntry : targetEntry.second) {
const BlockPolicy &policy = clientEntry.second;
dumpInfo += " ClientPid: " + std::to_string(policy.clientPid) + "\n";
dumpInfo += " BlockedSensorTypes: ";
for (const auto &sensorType : policy.sensorTypes) {
dumpInfo += std::to_string(sensorType) + " ";
}
dumpInfo += "\n";
}
}
return dumpInfo;
}
}
}