* 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 "permission_mapper.h"
#include <algorithm>
namespace OHOS::Plugin {
PermissionMapper& PermissionMapper::Instance()
{
static PermissionMapper instance;
return instance;
}
PermissionMapper::PermissionMapper()
{
singleMap_["ohos.permission.CAMERA"] = "android.permission.CAMERA";
singleMap_["ohos.permission.MICROPHONE"] = "android.permission.RECORD_AUDIO";
singleMap_["ohos.permission.READ_IMAGEVIDEO"] = "android.permission.READ_EXTERNAL_STORAGE";
singleMap_["ohos.permission.WRITE_IMAGEVIDEO"] = "android.permission.WRITE_EXTERNAL_STORAGE";
singleMap_["ohos.permission.APPROXIMATELY_LOCATION"] = "android.permission.ACCESS_COARSE_LOCATION";
singleMap_["ohos.permission.LOCATION"] = "android.permission.ACCESS_FINE_LOCATION";
multipleMap_["ohos.permission.ACCESS_BLUETOOTH"] = {
"android.permission.BLUETOOTH",
"android.permission.BLUETOOTH_ADMIN",
"android.permission.BLUETOOTH_ADVERTISE",
"android.permission.BLUETOOTH_CONNECT",
"android.permission.BLUETOOTH_SCAN",
"android.permission.ACCESS_FINE_LOCATION",
"android.permission.ACCESS_COARSE_LOCATION",
};
}
PermissionMapper::SingleResult PermissionMapper::ToAndroidSingle(const std::string& ohPerm) const
{
auto it = singleMap_.find(ohPerm);
if (it != singleMap_.end()) {
return {it->second, true};
}
return {ohPerm, false};
}
PermissionMapper::MultiResult PermissionMapper::ToAndroidMulti(const std::string& ohPerm) const
{
auto it = singleMap_.find(ohPerm);
if (it != singleMap_.end()) {
return {{it->second}, true};
}
auto mit = multipleMap_.find(ohPerm);
if (mit != multipleMap_.end()) {
return {mit->second, true};
}
return {{ohPerm}, false};
}
PermissionMapper::ReverseResult PermissionMapper::ReverseLookup(const std::string& androidPerm) const
{
for (const auto& [ohPerm, androidPerm_] : singleMap_) {
if (androidPerm_ == androidPerm) {
return {ohPerm, true};
}
}
for (const auto& [ohPerm, androidPerms] : multipleMap_) {
if (std::find(androidPerms.begin(), androidPerms.end(), androidPerm) != androidPerms.end()) {
return {ohPerm, true};
}
}
return {androidPerm, false};
}
std::string PermissionMapper::ToOhPermission(const std::string& androidPerm) const
{
return ReverseLookup(androidPerm).ohPermission;
}
PermissionMapper::AggregateResult PermissionMapper::AggregateToOh(
const std::vector<std::string>& androidPerms, const std::vector<int>& androidResults) const
{
static constexpr int invalidResult = 2;
if (androidPerms.size() != androidResults.size()) {
return {};
}
std::map<std::string, int> resultMap;
for (size_t i = 0; i < androidPerms.size(); i++) {
auto reverse = ReverseLookup(androidPerms[i]);
auto iter = resultMap.find(reverse.ohPermission);
if (iter != resultMap.end()) {
iter->second = (iter->second == androidResults[i]) ? iter->second : invalidResult;
} else if (!reverse.found) {
resultMap[reverse.ohPermission] = invalidResult;
} else {
resultMap[reverse.ohPermission] = androidResults[i];
}
}
AggregateResult result;
for (const auto& [perm, grantResult] : resultMap) {
result.ohPermissions.emplace_back(perm);
result.grantResults.emplace_back(grantResult);
}
return result;
}
}