* Copyright (c) 2024-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 "ipc_utilities.h"
#include <atomic>
#include "debug_logger.h"
#include "hiperf_hilog.h"
#include "utilities.h"
#if defined(is_ohos) && is_ohos && defined(BUNDLE_FRAMEWORK_ENABLE)
#include "application_info.h"
#include "bundle_mgr_proxy.h"
using ApplicationInfo = OHOS::AppExecFwk::ApplicationInfo;
using BundleMgrProxy = OHOS::sptr<OHOS::AppExecFwk::IBundleMgr>;
#else
using ApplicationInfo = void*;
using BundleMgrProxy = void*;
#endif
#if defined(is_ohos) && is_ohos
#include "iservice_registry.h"
#include "system_ability_definition.h"
#endif
namespace OHOS::Developtools::HiPerf {
static std::atomic<bool> g_haveIpc = false;
#if defined(is_ohos) && is_ohos && defined(BUNDLE_FRAMEWORK_ENABLE)
static constexpr int32_t GET_BUNDLEINFO_FLAGS =
static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION);
#endif
BundleMgrProxy GetBundleMgrProxy(std::string& err)
{
#if defined(is_ohos) && is_ohos && defined(BUNDLE_FRAMEWORK_ENABLE)
err.clear();
sptr<ISystemAbilityManager> sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
if (sam == nullptr) {
err = "GetSystemAbilityManager failed!";
return nullptr;
}
sptr<IRemoteObject> remoteObject = sam->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
if (remoteObject == nullptr) {
err = "Get BundleMgr SA failed!";
return nullptr;
}
sptr<AppExecFwk::IBundleMgr> proxy = iface_cast<AppExecFwk::IBundleMgr>(remoteObject);
if (proxy == nullptr) {
err = "iface_cast failed!";
return nullptr;
}
return proxy;
#else
err = "Not support bundle framework!";
return nullptr;
#endif
}
bool GetAppInfo(const std::string& bundleName, ApplicationInfo& appInfo, int32_t flags)
{
#if defined(is_ohos) && is_ohos && defined(BUNDLE_FRAMEWORK_ENABLE)
std::string err = "";
sptr<AppExecFwk::IBundleMgr> proxy = GetBundleMgrProxy(err);
if (proxy == nullptr) {
HIPERF_HILOGE(MODULE_DEFAULT, "GetAppInfo error, err: [%{public}s]", err.c_str());
return false;
}
AppExecFwk::BundleInfo bundleInfo;
auto ret = proxy->GetBundleInfoV9(bundleName, flags, bundleInfo, AppExecFwk::Constants::ANY_USERID);
if (ret != ERR_OK) {
HIPERF_HILOGE(MODULE_DEFAULT, "GetAppInfo error, err: GetBundleInfo failed!");
return false;
}
appInfo = bundleInfo.applicationInfo;
return true;
#else
HIPERF_HILOGE(MODULE_DEFAULT, "GetAppInfo error, err: not support bundle framework!");
return false;
#endif
}
bool IsDebugableApp(const std::string& bundleName)
{
#if defined(is_ohos) && is_ohos && defined(BUNDLE_FRAMEWORK_ENABLE)
g_haveIpc.store(true);
std::string err = "";
if (bundleName.empty()) {
HIPERF_HILOGE(MODULE_DEFAULT, "IsDebugableApp error, err: [bundleName is empty!]");
return false;
}
sptr<AppExecFwk::IBundleMgr> proxy = GetBundleMgrProxy(err);
if (proxy == nullptr) {
HIPERF_HILOGE(MODULE_DEFAULT, "IsDebugableApp error, err: [%{public}s]", err.c_str());
return false;
}
bool isDebugApp = false;
auto ret = proxy->IsDebuggableApplication(bundleName, isDebugApp);
if (ret != ERR_OK) {
HLOGE("IsDebugableApp error, err: IsDebuggableApplication failed!");
return false;
}
if (!isDebugApp) {
HLOGE("IsDebugableApp error, err: app is not debuggable");
return false;
}
HLOGI("app is debuggable");
return true;
#else
return false;
#endif
}
bool IsApplicationEncryped(const int pid)
{
#if defined(is_ohos) && is_ohos && defined(BUNDLE_FRAMEWORK_ENABLE)
g_haveIpc.store(true);
CHECK_TRUE(pid > 0, true, LOG_TYPE_PRINTF, "Invalid -p value '%d', the pid should be larger than 0\n", pid);
std::string bundleName = GetProcessName(pid);
CHECK_TRUE(!bundleName.empty(), true, 1, "bundleName is empty,pid is %d", pid);
auto pos = bundleName.find(":");
if (pos != std::string::npos) {
bundleName = bundleName.substr(0, pos);
}
AppExecFwk::ApplicationInfo appInfo;
bool ret = GetAppInfo(bundleName, appInfo, GET_BUNDLEINFO_FLAGS);
CHECK_TRUE(ret, true, 1, "%s:%s GetApplicationInfo failed!", __func__, bundleName.c_str());
bool isEncrypted = (appInfo.applicationReservedFlag &
static_cast<uint32_t>(AppExecFwk::ApplicationReservedFlag::ENCRYPTED_APPLICATION)) != 0;
HLOGD("check application encryped.%d : %s, pid:%d", isEncrypted, bundleName.c_str(), pid);
return isEncrypted;
#else
return false;
#endif
}
bool IsProfileableApp(const std::string& bundleName)
{
#if defined(is_ohos) && is_ohos && defined(BUNDLE_FRAMEWORK_ENABLE)
g_haveIpc.store(true);
if (bundleName.empty()) {
HIPERF_HILOGE(MODULE_DEFAULT, "IsProfileableApp error, err: [bundleName is empty!]");
return false;
}
AppExecFwk::ApplicationInfo appInfo;
if (!GetAppInfo(bundleName, appInfo, GET_BUNDLEINFO_FLAGS)) {
return false;
}
if (!appInfo.profileable) {
HLOGE("app is not profileable");
return false;
}
HLOGI("app is profileable app");
return true;
#else
return false;
#endif
}
void CheckIpcBeforeFork()
{
if (g_haveIpc.load()) {
HIPERF_HILOGW(MODULE_DEFAULT, "fork after ipc!");
}
}
}