* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "permission_utils.h"
#include "accesstoken_kit.h"
#include "ipc_skeleton.h"
#include "iservice_registry.h"
#include "privacy_kit.h"
#include "ringtone_log.h"
#include "ringtone_tracer.h"
#include "system_ability_definition.h"
#include "tokenid_kit.h"
namespace OHOS {
namespace Media {
using namespace std;
using namespace OHOS::Security::AccessToken;
using namespace OHOS::AppExecFwk::Constants;
sptr<AppExecFwk::IBundleMgr> RingtonePermissionUtils::bundleManager_ = nullptr;
mutex RingtonePermissionUtils::bundleManagerMutex_;
sptr<AppExecFwk::IBundleMgr> RingtonePermissionUtils::GetSysBundleManager()
{
if (bundleManager_ != nullptr) {
return bundleManager_;
}
lock_guard<mutex> lock(bundleManagerMutex_);
if (bundleManager_ != nullptr) {
return bundleManager_;
}
auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
if (systemAbilityManager == nullptr) {
RINGTONE_ERR_LOG("Failed to get SystemAbilityManager.");
return nullptr;
}
auto bundleObj = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
if (bundleObj == nullptr) {
RINGTONE_ERR_LOG("Remote object is nullptr.");
return nullptr;
}
auto bundleManager = iface_cast<AppExecFwk::IBundleMgr>(bundleObj);
if (bundleManager == nullptr) {
RINGTONE_ERR_LOG("Failed to iface_cast");
return nullptr;
}
bundleManager_ = bundleManager;
return bundleManager_;
}
void RingtonePermissionUtils::GetClientBundle(const int uid, string &bundleName)
{
bundleManager_ = GetSysBundleManager();
if (bundleManager_ == nullptr) {
bundleName = "";
return;
}
auto result = bundleManager_->GetBundleNameForUid(uid, bundleName);
if (!result) {
RINGTONE_ERR_LOG("GetBundleNameForUid fail");
bundleName = "";
}
}
bool RingtonePermissionUtils::CheckCallerPermission(const string &permission)
{
RingtoneTracer tracer;
tracer.Start("CheckCallerPermission");
AccessTokenID tokenCaller = IPCSkeleton::GetCallingTokenID();
int result = AccessTokenKit::VerifyAccessToken(tokenCaller, permission);
if (result != PermissionState::PERMISSION_GRANTED) {
RINGTONE_ERR_LOG("Have no media permission: %{public}s", permission.c_str());
return false;
}
return true;
}
bool RingtonePermissionUtils::CheckHasPermission(const vector<string> &permsVec)
{
if (permsVec.empty()) {
return false;
}
for (const auto &perm : permsVec) {
if (CheckCallerPermission(perm)) {
return true;
}
}
return false;
}
string RingtonePermissionUtils::GetPackageNameByBundleName(const string &bundleName)
{
const static int32_t invalidUid = -1;
const static int32_t baseUserRange = 200000;
int uid = IPCSkeleton::GetCallingUid();
if (uid <= invalidUid) {
RINGTONE_ERR_LOG("Get invalidUid UID %{public}d", uid);
return "";
}
int32_t userId = uid / baseUserRange;
RINGTONE_DEBUG_LOG("uid:%{private}d, userId:%{private}d", uid, userId);
AAFwk::Want want;
auto bundleManager_ = GetSysBundleManager();
if (bundleManager_ == nullptr) {
RINGTONE_ERR_LOG("Get BundleManager failed");
return "";
}
int ret = bundleManager_->GetLaunchWantForBundle(bundleName, want, userId);
if (ret != ERR_OK) {
RINGTONE_ERR_LOG("Can not get bundleName by want, err=%{public}d, userId=%{private}d",
ret, userId);
return "";
}
string abilityName = want.GetOperation().GetAbilityName();
return bundleManager_->GetAbilityLabel(bundleName, abilityName);
}
bool RingtonePermissionUtils::CheckCallerPermission(const vector<string> &permsVec)
{
if (permsVec.empty()) {
return false;
}
for (const auto &perm : permsVec) {
if (!CheckCallerPermission(perm)) {
return false;
}
}
return true;
}
uint32_t RingtonePermissionUtils::GetTokenId()
{
return IPCSkeleton::GetCallingTokenID();
}
bool RingtonePermissionUtils::IsSystemApp()
{
uint64_t tokenId = IPCSkeleton::GetCallingFullTokenID();
return TokenIdKit::IsSystemAppByFullTokenID(tokenId);
}
bool RingtonePermissionUtils::CheckIsSystemAppByUid()
{
int uid = IPCSkeleton::GetCallingUid();
bundleManager_ = GetSysBundleManager();
if (bundleManager_ == nullptr) {
RINGTONE_ERR_LOG("Can not get bundleMgr");
return false;
}
return bundleManager_->CheckIsSystemAppByUid(uid);
}
bool RingtonePermissionUtils::IsNativeSAApp()
{
uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
ATokenTypeEnum tokenType = AccessTokenKit::GetTokenTypeFlag(tokenId);
RINGTONE_DEBUG_LOG("check if native sa token, tokenId:%{public}d, tokenType:%{public}d", tokenId, tokenType);
if (tokenType == ATokenTypeEnum::TOKEN_NATIVE) {
return true;
}
return false;
}
}
}