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 
16 #include "drv_bundle_state_callback.h"
17 
18 #include <want.h>
19 #include <element_name.h>
20 
21 #include "system_ability_definition.h"
22 #include "iservice_registry.h"
23 #include "bundle_constants.h"
24 #include "os_account_manager.h"
25 #include  "pkg_db_helper.h"
26 
27 #include "hdf_log.h"
28 #include "edm_errors.h"
29 #include "hilog_wrapper.h"
30 #include "hitrace_meter.h"
31 #include "bus_extension_core.h"
32 #include "accesstoken_kit.h"
33 #include <unordered_map>
34 #include <pthread.h>
35 #include <thread>
36 namespace OHOS {
37 namespace ExternalDeviceManager {
38 using namespace std;
39 using namespace OHOS;
40 using namespace OHOS::AAFwk;
41 using namespace OHOS::AppExecFwk;
42 using namespace OHOS::ExternalDeviceManager;
43 using namespace OHOS::Security::AccessToken;
44 
45 constexpr uint64_t LABEL = HITRACE_TAG_OHOS;
46 const string DRV_INFO_BUS = "bus";
47 const string DRV_INFO_VENDOR = "vendor";
48 const string DRV_INFO_DESC = "description";
49 
50 static constexpr const char *BUNDLE_RESET_TASK_NAME = "DRIVER_INFO_RESET";
51 static constexpr const char *BUNDLE_UPDATE_TASK_NAME = "DRIVER_INFO_UPDATE";
52 static constexpr const char *GET_DRIVERINFO_TASK_NAME = "GET_DRIVERINFO_ASYNC";
53 
GetBundleSize(const std::string & bundleName)54 std::string DrvBundleStateCallback::GetBundleSize(const std::string &bundleName)
55 {
56     std::string bundleSize = "";
57     auto iBundleMgr = GetBundleMgrProxy();
58     if (iBundleMgr == nullptr) {
59         EDM_LOGE(MODULE_PKG_MGR, "Can not get iBundleMgr");
60         return bundleSize;
61     }
62     int32_t userId = GetCurrentActiveUserId();
63     std::vector<int64_t> bundleStats;
64     if (!iBundleMgr->GetBundleStats(bundleName, userId, bundleStats)) {
65         EDM_LOGE(MODULE_PKG_MGR, "GetBundleStats failed");
66         return bundleSize;
67     }
68     if (!bundleStats.empty()) {
69         bundleSize.append(std::to_string(bundleStats[0]));
70     }
71     return bundleSize;
72 }
73 
ChangeValue(DriverInfo & tmpDrvInfo,const map<string,string> & metadata)74 void DrvBundleStateCallback::ChangeValue(DriverInfo &tmpDrvInfo, const map<string, string> &metadata)
75 {
76     for (auto data : metadata) {
77         if (data.first == DRV_INFO_BUS) {
78             tmpDrvInfo.bus_ = data.second;
79         }
80         if (data.first == DRV_INFO_VENDOR) {
81             tmpDrvInfo.vendor_ = data.second;
82         }
83         if (data.first == DRV_INFO_DESC) {
84             tmpDrvInfo.description_ = data.second;
85         }
86     }
87 }
88 
ParseToPkgInfoTables(const std::vector<ExtensionAbilityInfo> & driverInfos,std::vector<PkgInfoTable> & pkgInfoTables)89 void DrvBundleStateCallback::ParseToPkgInfoTables(const std::vector<ExtensionAbilityInfo> &driverInfos,
90     std::vector<PkgInfoTable> &pkgInfoTables)
91 {
92     std::unordered_map<std::string, std::string> bundlesSize;
93     shared_ptr<IBusExtension> extInstance = nullptr;
94     for (const auto &driverInfo : driverInfos) {
95         if (driverInfo.type != ExtensionAbilityType::DRIVER || driverInfo.metadata.empty()) {
96             continue;
97         }
98         DriverInfo tmpDrvInfo(driverInfo.bundleName, driverInfo.name);
99         map<string, string> metaMap;
100         for (auto meta : driverInfo.metadata) {
101             metaMap.emplace(meta.name, meta.value);
102         }
103         ChangeValue(tmpDrvInfo, metaMap);
104         extInstance = BusExtensionCore::GetInstance().GetBusExtensionByName(tmpDrvInfo.GetBusName());
105         if (extInstance == nullptr) {
106             EDM_LOGE(MODULE_PKG_MGR, "GetBusExtensionByName failed, bus:%{public}s", tmpDrvInfo.bus_.c_str());
107             continue;
108         }
109         tmpDrvInfo.driverInfoExt_ = extInstance->ParseDriverInfo(metaMap);
110         if (tmpDrvInfo.driverInfoExt_ == nullptr) {
111             EDM_LOGE(MODULE_PKG_MGR, "ParseDriverInfo null");
112             continue;
113         }
114 
115         if (bundlesSize.find(driverInfo.bundleName) == bundlesSize.end()) {
116             std::string bundleSize = GetBundleSize(driverInfo.bundleName);
117             bundlesSize.emplace(driverInfo.bundleName, bundleSize);
118         }
119 
120         tmpDrvInfo.driverSize_ = bundlesSize[driverInfo.bundleName];
121         tmpDrvInfo.version_ = driverInfo.applicationInfo.versionName;
122         string driverInfoStr;
123         if (tmpDrvInfo.Serialize(driverInfoStr) != EDM_OK) {
124             EDM_LOGE(MODULE_PKG_MGR, "Serialize driverInfo faild");
125             continue;
126         }
127 
128         PkgInfoTable pkgInfo = CreatePkgInfoTable(driverInfo, driverInfoStr);
129         pkgInfoTables.emplace_back(pkgInfo);
130     }
131 }
132 
CreatePkgInfoTable(const ExtensionAbilityInfo & driverInfo,string driverInfoStr)133 PkgInfoTable DrvBundleStateCallback::CreatePkgInfoTable(const ExtensionAbilityInfo &driverInfo, string driverInfoStr)
134 {
135     PkgInfoTable pkgInfo = {
136         .driverUid = driverInfo.name + "-" + std::to_string(driverInfo.applicationInfo.accessTokenId),
137         .bundleAbility = driverInfo.bundleName + "-" + driverInfo.name,
138         .bundleName = driverInfo.bundleName,
139         .driverName = driverInfo.name,
140         .driverInfo = driverInfoStr
141     };
142     HapTokenInfo hapTokenInfo;
143     if (AccessTokenKit::GetHapTokenInfo(driverInfo.applicationInfo.accessTokenId, hapTokenInfo)
144         == AccessTokenKitRet::RET_SUCCESS) {
145         pkgInfo.userId = hapTokenInfo.userID;
146         pkgInfo.appIndex = hapTokenInfo.instIndex;
147         EDM_LOGD(MODULE_PKG_MGR, "userId:%{public}d, appIndex:%{public}d",
148             hapTokenInfo.userID, hapTokenInfo.instIndex);
149     }
150     return pkgInfo;
151 }
152 
DrvBundleStateCallback()153 DrvBundleStateCallback::DrvBundleStateCallback()
154 {
155     stiching.clear();
156     stiching += "-";
157 };
158 
DrvBundleStateCallback(shared_future<int32_t> bmsFuture,shared_future<int32_t> accountFuture,shared_future<int32_t> commEventFuture)159 DrvBundleStateCallback::DrvBundleStateCallback(shared_future<int32_t> bmsFuture, shared_future<int32_t> accountFuture,
160     shared_future<int32_t> commEventFuture): DrvBundleStateCallback()
161 {
162     bmsFuture_ = bmsFuture;
163     accountFuture_ = accountFuture;
164     commEventFuture_ = commEventFuture;
165 }
166 
~DrvBundleStateCallback()167 DrvBundleStateCallback::~DrvBundleStateCallback()
168 {
169     return;
170 };
171 
PrintTest()172 void DrvBundleStateCallback::PrintTest()
173 {
174     std::vector<std::string> allBundleAbilityNames;
175     std::shared_ptr<PkgDbHelper> helper = PkgDbHelper::GetInstance();
176     int32_t ret = helper->QueryAllSize(allBundleAbilityNames);
177     if (ret <= 0) {
178         EDM_LOGE(MODULE_PKG_MGR, "QueryAllSize failed");
179         return;
180     }
181     cout << "allBundleAbilityNames_ size = " << allBundleAbilityNames.size() << endl;
182 }
183 
OnBundleStateChanged(const uint8_t installType,const int32_t resultCode,const std::string & resultMsg,const std::string & bundleName)184 void DrvBundleStateCallback::OnBundleStateChanged(const uint8_t installType, const int32_t resultCode,
185     const std::string &resultMsg, const std::string &bundleName)
186 {
187     EDM_LOGI(MODULE_PKG_MGR, "OnBundleStateChanged");
188     return;
189 };
190 
191 /**
192     * @brief Called when a new application package has been installed on the device.
193     * @param bundleName Indicates the name of the bundle whose state has been installed.
194     * @param userId Indicates the id of the bundle whose state has been installed.
195     */
OnBundleAdded(const std::string & bundleName,const int userId)196 void DrvBundleStateCallback::OnBundleAdded(const std::string &bundleName, const int userId)
197 {
198     EDM_LOGI(MODULE_PKG_MGR, "OnBundleAdded");
199     StartTrace(LABEL, "OnBundleAdded");
200     if (!IsCurrentUserId(userId)) {
201         return;
202     }
203     std::vector<ExtensionAbilityInfo> driverInfos;
204     if (!QueryDriverInfos(bundleName, userId, driverInfos) || driverInfos.empty()) {
205         return;
206     }
207 
208     if (!UpdateToRdb(driverInfos, bundleName)) {
209         EDM_LOGE(MODULE_PKG_MGR, "OnBundleAdded error");
210     }
211     FinishTrace(LABEL);
212 }
213 /**
214     * @brief Called when a new application package has been Updated on the device.
215     * @param bundleName Indicates the name of the bundle whose state has been Updated.
216     * @param userId Indicates the id of the bundle whose state has been Updated.
217     */
OnBundleUpdated(const std::string & bundleName,const int userId)218 void DrvBundleStateCallback::OnBundleUpdated(const std::string &bundleName, const int userId)
219 {
220     EDM_LOGI(MODULE_PKG_MGR, "OnBundleUpdated");
221     StartTrace(LABEL, "OnBundleUpdated");
222     if (!IsCurrentUserId(userId)) {
223         return;
224     }
225     std::vector<ExtensionAbilityInfo> driverInfos;
226     if (!QueryDriverInfos(bundleName, userId, driverInfos)) {
227         return;
228     }
229 
230     if (driverInfos.empty()) {
231         OnBundleDrvRemoved(bundleName);
232         return;
233     }
234 
235     if (!UpdateToRdb(driverInfos, bundleName)) {
236         EDM_LOGE(MODULE_PKG_MGR, "OnBundleUpdated error");
237     }
238     FinishTrace(LABEL);
239 }
240 
241 /**
242     * @brief Called when a new application package has been Removed on the device.
243     * @param bundleName Indicates the name of the bundle whose state has been Removed.
244     * @param userId Indicates the id of the bundle whose state has been Removed.
245     */
OnBundleRemoved(const std::string & bundleName,const int userId)246 void DrvBundleStateCallback::OnBundleRemoved(const std::string &bundleName, const int userId)
247 {
248     EDM_LOGI(MODULE_PKG_MGR, "OnBundleRemoved");
249     StartTrace(LABEL, "OnBundleRemoved");
250     if (!IsCurrentUserId(userId)) {
251         return;
252     }
253     OnBundleDrvRemoved(bundleName);
254     FinishTrace(LABEL);
255 }
256 
AsObject()257 sptr<IRemoteObject> DrvBundleStateCallback::AsObject()
258 {
259     return nullptr;
260 }
261 
ResetInitOnce()262 void DrvBundleStateCallback::ResetInitOnce()
263 {
264     std::lock_guard<std::mutex> lock(initOnceMutex_);
265     initOnce = false;
266 }
267 
ResetMatchedBundles(const int32_t userId)268 void DrvBundleStateCallback::ResetMatchedBundles(const int32_t userId)
269 {
270     if (bundleUpdateCallback_ == nullptr) {
271         EDM_LOGE(MODULE_PKG_MGR, "DrvBundleStateCallback::ResetMatchedBundles bundleUpdateCallback_ is null");
272         return;
273     }
274     std::thread taskThread([userId, this]() {
275         bundleUpdateCallback_->OnBundlesReseted(userId);
276     });
277     pthread_setname_np(taskThread.native_handle(), BUNDLE_RESET_TASK_NAME);
278     taskThread.detach();
279 }
280 
GetAllDriverInfos(bool isExecCallback)281 bool DrvBundleStateCallback::GetAllDriverInfos(bool isExecCallback)
282 {
283     std::lock_guard<std::mutex> lock(initOnceMutex_);
284     if (initOnce) {
285         EDM_LOGI(MODULE_PKG_MGR, "GetAllDriverInfos has inited");
286         return true;
287     }
288     // query history bundle
289     auto iBundleMgr = GetBundleMgrProxy();
290     if (iBundleMgr == nullptr) {
291         EDM_LOGE(MODULE_PKG_MGR, "Can not get iBundleMgr");
292         return false;
293     }
294     std::vector<ExtensionAbilityInfo> driverInfos;
295     int32_t userId = GetCurrentActiveUserId();
296     if (userId == Constants::INVALID_USERID) {
297         EDM_LOGI(MODULE_PKG_MGR, "GetCurrentActiveUserId userId is invalid");
298         return false;
299     }
300     EDM_LOGI(MODULE_PKG_MGR, "QueryExtensionAbilityInfos userId:%{public}d", userId);
301     iBundleMgr->QueryExtensionAbilityInfos(ExtensionAbilityType::DRIVER, userId, driverInfos);
302     if (!UpdateToRdb(driverInfos, "", isExecCallback)) {
303         EDM_LOGE(MODULE_PKG_MGR, "UpdateToRdb failed");
304         return false;
305     }
306     initOnce = true;
307     return true;
308 }
309 
GetAllDriverInfosAsync(bool isExecCallback)310 void DrvBundleStateCallback::GetAllDriverInfosAsync(bool isExecCallback)
311 {
312     EDM_LOGI(MODULE_PKG_MGR, "GetAllDriverInfosAsync enter");
313     std::thread taskThread([isExecCallback, this]() {
314         bmsFuture_.wait();
315         accountFuture_.wait();
316         if (!GetAllDriverInfos(isExecCallback)) {
317             EDM_LOGE(MODULE_PKG_MGR, "GetAllDriverInfos failed");
318         }
319     });
320     pthread_setname_np(taskThread.native_handle(), GET_DRIVERINFO_TASK_NAME);
321     taskThread.detach();
322 }
323 
GetStiching()324 string DrvBundleStateCallback::GetStiching()
325 {
326     return stiching;
327 }
328 
CheckBundleMgrProxyPermission()329 bool DrvBundleStateCallback::CheckBundleMgrProxyPermission()
330 {
331     // check permission
332     auto iBundleMgr = GetBundleMgrProxy();
333     if (iBundleMgr == nullptr) {
334         EDM_LOGE(MODULE_PKG_MGR, "Can not get iBundleMgr");
335         return false;
336     }
337     if (!iBundleMgr->VerifySystemApi(Constants::INVALID_API_VERSION)) {
338         EDM_LOGE(MODULE_PKG_MGR, "non-system app calling system api");
339         return false;
340     }
341     if (!iBundleMgr->VerifyCallingPermission(Constants::LISTEN_BUNDLE_CHANGE)) {
342         EDM_LOGE(MODULE_PKG_MGR, "register bundle status callback failed due to lack of permission");
343         return false;
344     }
345     return true;
346 }
347 
QueryDriverInfos(const std::string & bundleName,const int userId,std::vector<ExtensionAbilityInfo> & driverInfos)348 bool DrvBundleStateCallback::QueryDriverInfos(const std::string &bundleName, const int userId,
349     std::vector<ExtensionAbilityInfo> &driverInfos)
350 {
351     if (bundleName.empty()) {
352         EDM_LOGE(MODULE_PKG_MGR, "BundleName empty");
353         return false;
354     }
355 
356     if (bundleMgr_ == nullptr) {
357         EDM_LOGE(MODULE_PKG_MGR, "BundleMgr_ nullptr");
358         return false;
359     }
360 
361     BundleInfo tmpBundleInfo;
362     int32_t flags = static_cast<int32_t>(GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_EXTENSION_ABILITY) + \
363                     static_cast<int32_t>(GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) + \
364                     static_cast<int32_t>(GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_METADATA);
365     if (!(bundleMgr_->GetBundleInfo(bundleName, flags, tmpBundleInfo, userId))) {
366         EDM_LOGE(MODULE_PKG_MGR, "GetBundleInfo err");
367         return false;
368     }
369 
370     for (auto &extensionInfo : tmpBundleInfo.extensionInfos) {
371         if (extensionInfo.type == ExtensionAbilityType::DRIVER) {
372             extensionInfo.applicationInfo = tmpBundleInfo.applicationInfo;
373             driverInfos.emplace_back(extensionInfo);
374         }
375     }
376     return true;
377 }
378 
ClearDriverInfo(DriverInfo & tmpDrvInfo)379 void DrvBundleStateCallback::ClearDriverInfo(DriverInfo &tmpDrvInfo)
380 {
381     tmpDrvInfo.bus_.clear();
382     tmpDrvInfo.vendor_.clear();
383     tmpDrvInfo.version_.clear();
384     tmpDrvInfo.driverInfoExt_ = nullptr;
385 }
386 
UpdateToRdb(const std::vector<ExtensionAbilityInfo> & driverInfos,const std::string & bundleName,bool isExecCallback)387 bool DrvBundleStateCallback::UpdateToRdb(const std::vector<ExtensionAbilityInfo> &driverInfos,
388     const std::string &bundleName, bool isExecCallback)
389 {
390     std::vector<PkgInfoTable> pkgInfoTables;
391     ParseToPkgInfoTables(driverInfos, pkgInfoTables);
392     std::shared_ptr<PkgDbHelper> helper = PkgDbHelper::GetInstance();
393     if (helper->AddOrUpdatePkgInfo(pkgInfoTables, bundleName) < PKG_OK) {
394         EDM_LOGE(MODULE_PKG_MGR, "add or update failed,bundleName:%{public}s", bundleName.c_str());
395         return false;
396     }
397 
398     if (isExecCallback && bundleUpdateCallback_ != nullptr) {
399         std::thread taskThread([bundleName, this]() {
400             bundleUpdateCallback_->OnBundlesUpdated(bundleName);
401         });
402         pthread_setname_np(taskThread.native_handle(), BUNDLE_UPDATE_TASK_NAME);
403         taskThread.detach();
404     }
405     return true;
406 }
407 
GetCurrentActiveUserId()408 int32_t DrvBundleStateCallback::GetCurrentActiveUserId()
409 {
410     int32_t localId;
411     int32_t ret = AccountSA::OsAccountManager::GetForegroundOsAccountLocalId(localId);
412     if (ret != 0) {
413         EDM_LOGE(MODULE_PKG_MGR, "GetForegroundOsAccountLocalId failed ret:%{public}d", ret);
414         return Constants::INVALID_USERID;
415     }
416     return localId;
417 }
418 
IsCurrentUserId(const int userId)419 bool DrvBundleStateCallback::IsCurrentUserId(const int userId)
420 {
421     return GetCurrentActiveUserId() == userId;
422 }
423 
GetBundleMgrProxy()424 sptr<OHOS::AppExecFwk::IBundleMgr> DrvBundleStateCallback::GetBundleMgrProxy()
425 {
426     if (bundleMgr_ == nullptr) {
427         std::lock_guard<std::mutex> lock(bundleMgrMutex_);
428         if (bundleMgr_ == nullptr) {
429             auto systemAbilityManager = OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
430             if (systemAbilityManager == nullptr) {
431                 EDM_LOGE(MODULE_PKG_MGR, "GetBundleMgr GetSystemAbilityManager is null");
432                 return nullptr;
433             }
434             auto bundleMgrSa = systemAbilityManager->GetSystemAbility(OHOS::BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
435             if (bundleMgrSa == nullptr) {
436                 EDM_LOGE(MODULE_PKG_MGR, "GetBundleMgr GetSystemAbility is null");
437                 return nullptr;
438             }
439             auto bundleMgr = OHOS::iface_cast<IBundleMgr>(bundleMgrSa);
440             if (bundleMgr == nullptr) {
441                 EDM_LOGE(MODULE_PKG_MGR, "GetBundleMgr iface_cast get null");
442             }
443             bundleMgr_ = bundleMgr;
444         }
445     }
446     return bundleMgr_;
447 }
448 
OnBundleDrvRemoved(const std::string & bundleName)449 void DrvBundleStateCallback::OnBundleDrvRemoved(const std::string &bundleName)
450 {
451     std::shared_ptr<PkgDbHelper> helper = PkgDbHelper::GetInstance();
452 
453     int32_t ret = helper->DeleteRightRecord(bundleName);
454     if (ret < 0) {
455         EDM_LOGE(MODULE_PKG_MGR, "delete failed: %{public}s", bundleName.c_str());
456         return;
457     }
458     if (bundleUpdateCallback_ != nullptr) {
459         std::thread taskThread([bundleName, this]() {
460             bundleUpdateCallback_->OnBundlesUpdated(bundleName);
461         });
462         pthread_setname_np(taskThread.native_handle(), BUNDLE_UPDATE_TASK_NAME);
463         taskThread.detach();
464     }
465 }
466 }
467 }