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 }