1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.. All rights reserved.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "vk_bundle_mgr_helper.h"
16
17 #include "iservice_registry.h"
18 #include "system_ability_definition.h"
19 #include "../loader_hilog.h"
20 #include <securec.h>
21 #define EOK 0
22
23 extern "C" {
24 void *loader_instance_heap_calloc(const struct loader_instance *instance,
25 size_t size, VkSystemAllocationScope allocation_scope);
26 }
27 constexpr const char *DEBUG_SANDBOX_DIR = "/data/storage/el1/bundle/";
28
InitBundleInfo(char* debugHapName)29 bool InitBundleInfo(char* debugHapName)
30 {
31 if (NULL == debugHapName || '\0' == debugHapName[0]) {
32 VKHILOGE("debug_hap_name is NULL!");
33 return false;
34 }
35 std::string debugHap(debugHapName);
36 auto vkBundleMgrHelper = OHOS::DelayedSingleton<OHOS::AppExecFwk::VKBundleMgrHelper>::GetInstance();
37 if (vkBundleMgrHelper == nullptr) {
38 VKHILOGE("vkBundleMgrHelper is null!");
39 return false;
40 }
41
42 if (vkBundleMgrHelper->GetBundleInfoForSelf(
43 OHOS::AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION, vkBundleMgrHelper->g_bundleInfo) ==
44 OHOS::ERR_OK) {
45 if (vkBundleMgrHelper->g_bundleInfo.name == debugHap) {
46 return true;
47 } else {
48 VKHILOGE("this hap is %{public}s, the debug hap is %{public}s",
49 vkBundleMgrHelper->g_bundleInfo.name.c_str(), debugHap.c_str());
50 }
51 } else {
52 VKHILOGE("Call GetBundleInfoForSelf func failed!");
53 }
54 return false;
55 }
56
GetDebugLayerLibPath(const struct loader_instance *inst, VkSystemAllocationScope allocation_sacope)57 char* GetDebugLayerLibPath(const struct loader_instance *inst, VkSystemAllocationScope allocation_sacope)
58 {
59 auto vkBundleMgrHelper = OHOS::DelayedSingleton<OHOS::AppExecFwk::VKBundleMgrHelper>::GetInstance();
60 std::string pathStr(DEBUG_SANDBOX_DIR);
61 std::string appLibPath = pathStr + vkBundleMgrHelper->g_bundleInfo.applicationInfo.nativeLibraryPath + "/";
62 const char* fullPath = appLibPath.c_str();
63 size_t len = strlen(fullPath) + 1;
64 char* libPath = static_cast<char*>(loader_instance_heap_calloc(inst, len, allocation_sacope));
65 if (libPath == NULL) {
66 VKHILOGE("malloc libPath fail");
67 return NULL;
68 }
69 if (memcpy_s(libPath, len, fullPath, len) != EOK) {
70 VKHILOGE("memcpy_s libPath fail, fullPath: %{public}s", fullPath);
71 return NULL;
72 }
73 VKHILOGD("GetDebugLayerLibPath(): the libPath is %{public}s", libPath);
74 return libPath;
75 }
76
77 namespace OHOS {
78 namespace AppExecFwk {
VKBundleMgrHelper()79 VKBundleMgrHelper::VKBundleMgrHelper() {}
80
~VKBundleMgrHelper()81 VKBundleMgrHelper::~VKBundleMgrHelper()
82 {
83 if (bundleMgr_ != nullptr && bundleMgr_->AsObject() != nullptr && deathRecipient_ != nullptr) {
84 bundleMgr_->AsObject()->RemoveDeathRecipient(deathRecipient_);
85 }
86 }
87
Connect()88 sptr<AppExecFwk::IBundleMgr> VKBundleMgrHelper::Connect()
89 {
90 VKHILOGD("Call VKBundleMgrHelper::Connect");
91 std::lock_guard<std::mutex> lock(mutex_);
92 if (bundleMgr_ == nullptr) {
93 sptr<ISystemAbilityManager> systemAbilityManager =
94 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
95 if (systemAbilityManager == nullptr) {
96 VKHILOGE("Failed to get system ability manager.");
97 return nullptr;
98 }
99 sptr<IRemoteObject> remoteObject_ = systemAbilityManager->GetSystemAbility(
100 BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
101 if (remoteObject_ == nullptr || (bundleMgr_ = iface_cast<IBundleMgr>(remoteObject_)) == nullptr) {
102 VKHILOGE("Failed to get bundle mgr service remote object");
103 return nullptr;
104 }
105 std::weak_ptr<VKBundleMgrHelper> weakPtr = shared_from_this();
106 auto deathCallback = [weakPtr](const wptr<IRemoteObject> &object) {
107 auto sharedPtr = weakPtr.lock();
108 if (sharedPtr == nullptr) {
109 VKHILOGE("Bundle helper instance is nullptr");
110 return;
111 }
112 sharedPtr->OnDeath();
113 };
114 deathRecipient_ = new(std::nothrow) VKBundleMgrServiceDeathRecipient(deathCallback);
115 if (deathRecipient_ == nullptr) {
116 VKHILOGE("Failed to create death recipient ptr deathRecipient_!");
117 return nullptr;
118 }
119 if (bundleMgr_->AsObject() != nullptr) {
120 bundleMgr_->AsObject()->AddDeathRecipient(deathRecipient_);
121 }
122 }
123 return bundleMgr_;
124 }
125
OnDeath()126 void VKBundleMgrHelper::OnDeath()
127 {
128 VKHILOGD("Call VKBundleMgrHelper::OnDeath");
129 std::lock_guard<std::mutex> lock(mutex_);
130 if (bundleMgr_ == nullptr || bundleMgr_->AsObject() == nullptr) {
131 VKHILOGE("bundleMgr_ is nullptr!");
132 return;
133 }
134 bundleMgr_->AsObject()->RemoveDeathRecipient(deathRecipient_);
135 bundleMgr_ = nullptr;
136 }
137
GetBundleInfoForSelf(AppExecFwk::GetBundleInfoFlag flags, BundleInfo &bundleInfo)138 ErrCode VKBundleMgrHelper::GetBundleInfoForSelf(AppExecFwk::GetBundleInfoFlag flags, BundleInfo &bundleInfo)
139 {
140 VKHILOGD("Call VKBundleMgrHealper::GetBundleInfoForSelf.");
141 auto bundleMgr_ = Connect();
142 if (bundleMgr_ == nullptr) {
143 VKHILOGE("Failed to connect.");
144 return -1;
145 }
146 return bundleMgr_->GetBundleInfoForSelf(static_cast<int32_t>(flags), bundleInfo);
147 }
148
VKBundleMgrServiceDeathRecipient( const std::function<void(const wptr<IRemoteObject>& object)>& deathCallback)149 VKBundleMgrServiceDeathRecipient::VKBundleMgrServiceDeathRecipient(
150 const std::function<void(const wptr<IRemoteObject>& object)>& deathCallback)
151 : deathCallback_(deathCallback) {}
152
OnRemoteDied(const wptr<IRemoteObject>& object)153 void VKBundleMgrServiceDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& object)
154 {
155 if (deathCallback_ != nullptr) {
156 deathCallback_(object);
157 }
158 }
159 }
160 }