1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
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 #define LOG_TAG "BundleMgrProxy"
16 #include "bundle_mgr_proxy.h"
17 
18 #include "account/account_delegate.h"
19 #include "datashare_errno.h"
20 #include "datashare_radar_reporter.h"
21 #include "if_system_ability_manager.h"
22 #include "iservice_registry.h"
23 #include "log_print.h"
24 #include "system_ability_definition.h"
25 #include "uri_utils.h"
26 
27 namespace OHOS::DataShare {
GetBundleMgrProxy()28 sptr<AppExecFwk::BundleMgrProxy> BundleMgrProxy::GetBundleMgrProxy()
29 {
30     std::lock_guard<std::mutex> lock(mutex_);
31     if (proxy_ != nullptr) {
32         return iface_cast<AppExecFwk::BundleMgrProxy>(proxy_);
33     }
34     proxy_ = CheckBMS();
35     if (proxy_ == nullptr) {
36         ZLOGE("BMS service not ready to complete.");
37         return nullptr;
38     }
39     deathRecipient_ = new (std::nothrow)BundleMgrProxy::ServiceDeathRecipient(weak_from_this());
40     if (deathRecipient_ == nullptr) {
41         ZLOGE("deathRecipient alloc failed.");
42         return nullptr;
43     }
44     if (!proxy_->AddDeathRecipient(deathRecipient_)) {
45         ZLOGE("add death recipient failed.");
46         proxy_ = nullptr;
47         deathRecipient_ = nullptr;
48         return nullptr;
49     }
50     return iface_cast<AppExecFwk::BundleMgrProxy>(proxy_);
51 }
52 
CheckBMS()53 sptr<IRemoteObject> BundleMgrProxy::CheckBMS()
54 {
55     sptr<ISystemAbilityManager> systemAbilityManager =
56         SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
57     if (systemAbilityManager == nullptr) {
58         ZLOGE("Failed to get system ability mgr.");
59         return nullptr;
60     }
61     return systemAbilityManager->CheckSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
62 }
63 
GetBundleInfoFromBMS(const std::string & bundleName,int32_t userId,BundleConfig & bundleConfig,int32_t appIndex)64 int BundleMgrProxy::GetBundleInfoFromBMS(
65     const std::string &bundleName, int32_t userId, BundleConfig &bundleConfig, int32_t appIndex)
66 {
67     std::string bundleKey = bundleName + std::to_string(userId);
68     if (appIndex != 0) {
69         bundleKey += "appIndex" + std::to_string(appIndex);
70     }
71     auto it = bundleCache_.Find(bundleKey);
72     if (it.first) {
73         bundleConfig = it.second;
74         return E_OK;
75     }
76     auto bmsClient = GetBundleMgrProxy();
77     if (bmsClient == nullptr) {
78         RADAR_REPORT(__FUNCTION__, RadarReporter::SILENT_ACCESS, RadarReporter::GET_BMS,
79             RadarReporter::FAILED, RadarReporter::ERROR_CODE, RadarReporter::GET_BMS_FAILED);
80         ZLOGE("GetBundleMgrProxy is nullptr!");
81         return E_BMS_NOT_READY;
82     }
83     AppExecFwk::BundleInfo bundleInfo;
84     bool ret;
85     if (appIndex == 0) {
86         ret = bmsClient->GetBundleInfo(
87             bundleName, AppExecFwk::BundleFlag::GET_BUNDLE_WITH_EXTENSION_INFO, bundleInfo, userId);
88     } else {
89         ret = bmsClient->GetCloneBundleInfo(
90             bundleName, static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_EXTENSION_ABILITY) |
91             static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE),
92             appIndex, bundleInfo, userId);
93         // when there is no error, the former function returns 1 while the new function returns 0
94         ret = !ret;
95         for (auto &item : bundleInfo.hapModuleInfos) {
96             for (auto &item2 : item.extensionInfos) {
97                 bundleInfo.extensionInfos.push_back(item2);
98             }
99         }
100     }
101 
102     if (!ret) {
103         RADAR_REPORT(__FUNCTION__, RadarReporter::SILENT_ACCESS, RadarReporter::GET_BMS,
104             RadarReporter::FAILED, RadarReporter::ERROR_CODE, RadarReporter::GET_BUNDLE_INFP_FAILED);
105         ZLOGE("GetBundleInfo failed!bundleName is %{public}s, userId is %{public}d", bundleName.c_str(), userId);
106         return E_BUNDLE_NAME_NOT_EXIST;
107     }
108     auto [errCode, bundle] = ConvertToDataShareBundle(bundleInfo);
109     if (errCode != E_OK) {
110         ZLOGE("Profile Unmarshall failed! bundleName:%{public}s", URIUtils::Anonymous(bundle.name).c_str());
111         return errCode;
112     }
113     bundleConfig = bundle;
114     bundleCache_.Insert(bundleKey, bundle);
115     return E_OK;
116 }
117 
OnProxyDied()118 void BundleMgrProxy::OnProxyDied()
119 {
120     std::lock_guard<std::mutex> lock(mutex_);
121     ZLOGE("bundleMgr died, proxy=null ? %{public}s.", proxy_ == nullptr ? "true" : "false");
122     if (proxy_ != nullptr) {
123         proxy_->RemoveDeathRecipient(deathRecipient_);
124     }
125     proxy_ = nullptr;
126     deathRecipient_ = nullptr;
127 }
128 
~BundleMgrProxy()129 BundleMgrProxy::~BundleMgrProxy()
130 {
131     std::lock_guard<std::mutex> lock(mutex_);
132     if (proxy_ != nullptr) {
133         proxy_->RemoveDeathRecipient(deathRecipient_);
134     }
135 }
136 
Delete(const std::string & bundleName,int32_t userId,int32_t appIndex)137 void BundleMgrProxy::Delete(const std::string &bundleName, int32_t userId, int32_t appIndex)
138 {
139     if (appIndex != 0) {
140         bundleCache_.Erase(bundleName + std::to_string(userId) + "appIndex" + std::to_string(appIndex));
141     } else {
142         bundleCache_.Erase(bundleName + std::to_string(userId));
143     }
144     return;
145 }
146 
GetInstance()147 std::shared_ptr<BundleMgrProxy> BundleMgrProxy::GetInstance()
148 {
149     static std::shared_ptr<BundleMgrProxy> proxy(new BundleMgrProxy());
150     return proxy;
151 }
152 
ConvertToDataShareBundle(AppExecFwk::BundleInfo & bundleInfo)153 std::pair<int, BundleConfig> BundleMgrProxy::ConvertToDataShareBundle(AppExecFwk::BundleInfo &bundleInfo)
154 {
155     BundleConfig bundleConfig;
156     bundleConfig.name = std::move(bundleInfo.name);
157     bundleConfig.singleton = std::move(bundleInfo.singleton);
158     auto [errCode, hapModuleInfos] = ConvertHapModuleInfo(bundleInfo);
159     if (errCode != E_OK) {
160         return std::make_pair(errCode, bundleConfig);
161     }
162     bundleConfig.hapModuleInfos = hapModuleInfos;
163 
164     auto [err, extensionInfos] = ConvertExtensionAbility(bundleInfo);
165     if (err != E_OK) {
166         return std::make_pair(err, bundleConfig);
167     }
168     bundleConfig.extensionInfos = extensionInfos;
169     return std::make_pair(E_OK, bundleConfig);
170 }
171 
ConvertExtensionAbility(AppExecFwk::BundleInfo & bundleInfo)172 std::pair<int, std::vector<ExtensionAbilityInfo>> BundleMgrProxy::ConvertExtensionAbility(
173     AppExecFwk::BundleInfo &bundleInfo)
174 {
175     std::vector<ExtensionAbilityInfo> extensionInfos;
176     for (auto &item : bundleInfo.extensionInfos) {
177         if (item.type != AppExecFwk::ExtensionAbilityType::DATASHARE) {
178             continue;
179         }
180         ExtensionAbilityInfo extensionInfo;
181         extensionInfo.type = std::move(item.type);
182         extensionInfo.readPermission = std::move(item.readPermission);
183         extensionInfo.writePermission = std::move(item.writePermission);
184         extensionInfo.uri = std::move(item.uri);
185         extensionInfo.resourcePath = std::move(item.resourcePath);
186         extensionInfo.hapPath = std::move(item.hapPath);
187         ProfileConfig profileConfig;
188         auto [ret, profileInfo] = DataShareProfileConfig::GetDataProperties(
189             item.metadata, extensionInfo.resourcePath, extensionInfo.hapPath, DATA_SHARE_EXTENSION_META);
190         if (ret == NOT_FOUND) {
191             profileConfig.resultCode = NOT_FOUND;
192         }
193         if (ret == ERROR) {
194             profileConfig.resultCode = ERROR;
195             ZLOGE("Profile unmarshall error.uri: %{public}s", URIUtils::Anonymous(extensionInfo.uri).c_str());
196             return std::make_pair(E_ERROR, extensionInfos);
197         }
198         profileConfig.profile = profileInfo;
199         extensionInfo.profileInfo = profileConfig;
200         extensionInfos.emplace_back(extensionInfo);
201     }
202     return std::make_pair(E_OK, extensionInfos);
203 }
204 
ConvertHapModuleInfo(AppExecFwk::BundleInfo & bundleInfo)205 std::pair<int, std::vector<HapModuleInfo>> BundleMgrProxy::ConvertHapModuleInfo(AppExecFwk::BundleInfo &bundleInfo)
206 {
207     std::vector<HapModuleInfo> hapModuleInfos;
208     for (auto &item : bundleInfo.hapModuleInfos) {
209         HapModuleInfo hapModuleInfo;
210         hapModuleInfo.resourcePath = std::move(item.resourcePath);
211         hapModuleInfo.hapPath = std::move(item.hapPath);
212         hapModuleInfo.moduleName = std::move(item.moduleName);
213         std::vector<ProxyData> proxyDatas;
214         for (auto &proxyData : item.proxyDatas) {
215             ProxyData data;
216             data.uri = std::move(proxyData.uri);
217             data.requiredReadPermission = std::move(proxyData.requiredReadPermission);
218             data.requiredWritePermission = std::move(proxyData.requiredWritePermission);
219             ProfileConfig profileConfig;
220             auto [ret, profileInfo] = DataShareProfileConfig::GetDataProperties(
221                 std::vector<AppExecFwk::Metadata>{proxyData.metadata}, hapModuleInfo.resourcePath,
222                 hapModuleInfo.hapPath, DATA_SHARE_PROPERTIES_META);
223             if (ret == NOT_FOUND) {
224                 profileConfig.resultCode = NOT_FOUND;
225             }
226             if (ret == ERROR) {
227                 profileConfig.resultCode = ERROR;
228                 ZLOGE("Profile unmarshall error.uri: %{public}s", URIUtils::Anonymous(data.uri).c_str());
229                 return std::make_pair(E_ERROR, hapModuleInfos);
230             }
231             profileConfig.profile = profileInfo;
232             data.profileInfo = profileConfig;
233             proxyDatas.emplace_back(data);
234         }
235         hapModuleInfo.proxyDatas = proxyDatas;
236         hapModuleInfos.emplace_back(hapModuleInfo);
237     }
238     return std::make_pair(E_OK, hapModuleInfos);
239 }
240 } // namespace OHOS::DataShare