* 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 "bundle_util.h"
#include "bundle_mgr_client.h"
#include "bundle_mgr_proxy.h"
#include "hiview_logger.h"
#include "iservice_registry.h"
namespace OHOS {
namespace HiviewDFX {
namespace BundleUtil {
namespace {
constexpr int BUNDLE_MGR_SERVICE_SYS_ABILITY_ID = 401;
constexpr int VALUE_MOD = 200000;
DEFINE_LOG_TAG("BundleUtils");
}
sptr<AppExecFwk::IBundleMgr> GetBundleManager()
{
sptr<ISystemAbilityManager> systemAbilityManager =
SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
if (!systemAbilityManager) {
HIVIEW_LOGE("fail to get system ability manager.");
return nullptr;
}
sptr<IRemoteObject> remoteObject = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
if (!remoteObject) {
HIVIEW_LOGE("fail to get bundle manager proxy.");
return nullptr;
}
sptr<AppExecFwk::IBundleMgr> bundleManager = iface_cast<AppExecFwk::IBundleMgr>(remoteObject);
if (bundleManager == nullptr) {
HIVIEW_LOGW("iface_cast bundleMgr is nullptr, let's try new proxy way.");
bundleManager = new (std::nothrow) AppExecFwk::BundleMgrProxy(remoteObject);
if (bundleManager == nullptr) {
HIVIEW_LOGE("fail to new bundle manager proxy.");
return nullptr;
}
}
return bundleManager;
}
std::string GetPathPlaceHolder(int32_t uid)
{
sptr<AppExecFwk::IBundleMgr> bundleMgr = GetBundleManager();
if (bundleMgr == nullptr) {
HIVIEW_LOGE("failed to get bundleManager");
return "";
}
std::string bundleName = "";
int32_t appIndex = -1;
if (bundleMgr->GetNameAndIndexForUid(uid, bundleName, appIndex) != ERR_OK || appIndex < 0) {
HIVIEW_LOGE("failed get name and index");
return "";
}
if (bundleName.empty()) {
HIVIEW_LOGE("bundleName get empty");
return "";
}
if (appIndex > 0) {
return "+clone-" + std::to_string(appIndex) + "+" + bundleName;
}
AppExecFwk::BundleInfo bundleInfo;
AppExecFwk::BundleMgrClient client;
if (!client.GetBundleInfo(bundleName, AppExecFwk::BundleFlag::GET_BUNDLE_INFO_EXCLUDE_EXT,
bundleInfo, uid / VALUE_MOD)) {
HIVIEW_LOGE("failed get bundleInfo");
return "";
}
if (!bundleInfo.entryInstallationFree) {
return bundleName;
}
std::string placeHolder;
if (client.GetDirByBundleNameAndAppIndex(bundleName, appIndex, placeHolder) != ERR_OK) {
HIVIEW_LOGE("failed get GetDirByBundleNameAndAppIndex");
return "";
}
return placeHolder;
}
int32_t GetUidByBundleName(const std::string& bundleName)
{
AppExecFwk::BundleInfo info;
AppExecFwk::BundleMgrClient client;
if (!client.GetBundleInfo(bundleName, AppExecFwk::GET_BUNDLE_DEFAULT, info,
AppExecFwk::Constants::ALL_USERID)) {
HIVIEW_LOGE("Failed to query uid from bms.");
} else {
HIVIEW_LOGD("bundleName of uid=%{public}d", info.uid);
}
return info.uid;
}
std::string GetApplicationNameById(int32_t uid)
{
std::string bundleName;
AppExecFwk::BundleMgrClient client;
if (client.GetNameForUid(uid, bundleName) != ERR_OK) {
HIVIEW_LOGW("Failed to query bundle name, uid:%{public}d.", uid);
}
return bundleName;
}
std::string GetSandBoxPath(int32_t uid, const std::string& mainDir, const std::string& subDir)
{
std::string pathHolder = GetPathPlaceHolder(uid);
if (pathHolder.empty() || mainDir.empty()) {
return "";
}
int userId = uid / VALUE_MOD;
return "/data/app/el2/" + std::to_string(userId) + "/" + mainDir + "/" + pathHolder + "/" + subDir;
}
std::string GetSandBoxPath(int32_t uid, const std::string& mainDir, const std::string& pathHolder,
const std::string& subDir)
{
if (pathHolder.empty() || mainDir.empty()) {
return "";
}
int userId = uid / VALUE_MOD;
return "/data/app/el2/" + std::to_string(userId) + "/" + mainDir + "/" + pathHolder + "/" + subDir;
}
bool IsDebugHap(const int32_t uid)
{
std::string bundleName = GetApplicationNameById(uid);
AppExecFwk::BundleMgrClient client;
AppExecFwk::BundleInfo info;
if (!client.GetBundleInfo(bundleName, AppExecFwk::BundleFlag::GET_BUNDLE_INFO_EXCLUDE_EXT,
info, AppExecFwk::Constants::ALL_USERID)) {
HIVIEW_LOGE("Failed to query BundleInfo from bms, bundle:%{public}s.", bundleName.c_str());
return false;
}
HIVIEW_LOGI("The is debug of %{public}s is %{public}d", bundleName.c_str(), info.applicationInfo.debug);
return info.applicationInfo.debug;
}
}
}
}