* Copyright (c) 2022-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 "bundle_manager_helper.h"
#include "accesstoken_kit.h"
#include "iservice_registry.h"
#include "system_ability_definition.h"
#include "tokenid_kit.h"
#include "continuous_task_log.h"
namespace OHOS {
namespace BackgroundTaskMgr {
#ifdef BGTASK_MGR_UNIT_TEST
#define WEAK_FUNC __attribute__((weak))
#else
#define WEAK_FUNC
#endif
using OHOS::AppExecFwk::Constants::PERMISSION_GRANTED;
BundleManagerHelper::BundleManagerHelper()
{
bundleMgrDeathRecipient_ = new (std::nothrow) RemoteDeathRecipient(
[this](const wptr<IRemoteObject> &object) { this->OnRemoteDied(object); });
}
BundleManagerHelper::~BundleManagerHelper()
{
std::lock_guard<std::mutex> lock(connectionMutex_);
Disconnect();
}
std::string BundleManagerHelper::GetClientBundleName(int32_t uid)
{
std::string bundle {""};
std::lock_guard<std::mutex> lock(connectionMutex_);
Connect();
if (bundleMgr_ != nullptr) {
bundleMgr_->GetNameForUid(uid, bundle);
}
BGTASK_LOGD("get client Bundle Name: %{public}s", bundle.c_str());
return bundle;
}
bool BundleManagerHelper::CheckPermission(const std::string &permission)
{
Security::AccessToken::AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID();
int32_t ret = Security::AccessToken::AccessTokenKit::VerifyAccessToken(callerToken, permission);
if (ret != Security::AccessToken::PermissionState::PERMISSION_GRANTED) {
BGTASK_LOGE("CheckPermission: %{public}s failed", permission.c_str());
return false;
}
return true;
}
bool BundleManagerHelper::CheckACLPermission(const std::string &permission, uint64_t callingTokenId)
{
int32_t ret = Security::AccessToken::AccessTokenKit::VerifyAccessToken(callingTokenId, permission);
if (ret != Security::AccessToken::PermissionState::PERMISSION_GRANTED) {
BGTASK_LOGD("CheckPermission: %{public}s failed", permission.c_str());
return false;
}
return true;
}
bool BundleManagerHelper::IsSystemApp(uint64_t fullTokenId)
{
return Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(fullTokenId);
}
bool BundleManagerHelper::GetBundleInfo(const std::string &bundleName, const AppExecFwk::BundleFlag flag,
AppExecFwk::BundleInfo &bundleInfo, int32_t userId)
{
std::lock_guard<std::mutex> lock(connectionMutex_);
Connect();
if (bundleMgr_ != nullptr && bundleMgr_->GetBundleInfo(bundleName, flag, bundleInfo, userId)) {
return true;
}
return false;
}
bool WEAK_FUNC BundleManagerHelper::GetApplicationInfo(const std::string &appName,
const AppExecFwk::ApplicationFlag flag, const int userId, AppExecFwk::ApplicationInfo &appInfo)
{
BGTASK_LOGD("start get application info");
std::lock_guard<std::mutex> lock(connectionMutex_);
Connect();
BGTASK_LOGD("bundleMgr is null: %{public}d ", bundleMgr_ == nullptr);
if (bundleMgr_ != nullptr && bundleMgr_->GetApplicationInfo(appName, flag, userId, appInfo)) {
return true;
}
return false;
}
bool BundleManagerHelper::QueryAbilityInfo(const AAFwk::Want &want, int32_t flags, int32_t userId,
AppExecFwk::AbilityInfo &abilityInfo)
{
std::lock_guard<std::mutex> lock(connectionMutex_);
Connect();
if (bundleMgr_ != nullptr && bundleMgr_->QueryAbilityInfo(want, flags, userId, abilityInfo)) {
return true;
}
return false;
}
bool BundleManagerHelper::GetBundleResourceInfo(const std::string &bundleName, const AppExecFwk::ResourceFlag flags,
AppExecFwk::BundleResourceInfo &bundleResourceInfo)
{
std::lock_guard<std::mutex> lock(connectionMutex_);
Connect();
if (bundleMgr_ == nullptr) {
return false;
}
sptr<AppExecFwk::IBundleResource> bundleResourceProxy = bundleMgr_->GetBundleResourceProxy();
if (bundleResourceProxy == nullptr) {
return false;
}
ErrCode result = bundleResourceProxy->
GetBundleResourceInfo(bundleName, static_cast<uint32_t>(flags), bundleResourceInfo);
if (result != ERR_OK) {
BGTASK_LOGE("GetBundleResourceInfo fail, errcode: %{public}d", result);
return false;
}
return true;
}
bool BundleManagerHelper::GetBundleInfoByFlags(const std::string &bundleName, int32_t flags,
AppExecFwk::BundleInfo &bundleInfo, int32_t userId)
{
std::lock_guard<std::mutex> lock(connectionMutex_);
Connect();
if (bundleMgr_ != nullptr && bundleMgr_->GetBundleInfo(bundleName, flags, bundleInfo, userId)) {
return true;
}
return false;
}
bool BundleManagerHelper::GetAppIndexAndBundleNameByUid(int32_t uid, int32_t &appIndex, std::string &bundleName)
{
std::lock_guard<std::mutex> lock(connectionMutex_);
Connect();
if (bundleMgr_ == nullptr) {
return false;
}
ErrCode ret = bundleMgr_->GetNameAndIndexForUid(uid, bundleName, appIndex);
if (ret == ERR_OK) {
return true;
}
return false;
}
bool BundleManagerHelper::Connect()
{
if (bundleMgr_ != nullptr) {
return true;
}
sptr<ISystemAbilityManager> systemAbilityManager =
SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
if (systemAbilityManager == nullptr) {
BGTASK_LOGE("get SystemAbilityManager failed");
return false;
}
sptr<IRemoteObject> remoteObject = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
if (remoteObject == nullptr) {
BGTASK_LOGE("get Bundle Manager failed");
return false;
}
bundleMgr_ = iface_cast<AppExecFwk::IBundleMgr>(remoteObject);
if (bundleMgr_ != nullptr && bundleMgrDeathRecipient_ != nullptr) {
bundleMgr_->AsObject()->AddDeathRecipient(bundleMgrDeathRecipient_);
return true;
}
BGTASK_LOGE("get bundleMgr failed");
return false;
}
void BundleManagerHelper::Disconnect()
{
if (bundleMgr_ != nullptr && bundleMgr_->AsObject() != nullptr) {
bundleMgr_->AsObject()->RemoveDeathRecipient(bundleMgrDeathRecipient_);
bundleMgr_ = nullptr;
}
}
void BundleManagerHelper::OnRemoteDied(const wptr<IRemoteObject> &object)
{
std::lock_guard<std::mutex> lock(connectionMutex_);
Disconnect();
}
}
}