• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "shared_bundle_installer.h"
17 
18 #include "app_log_wrapper.h"
19 #include "bundle_mgr_service.h"
20 #include "scope_guard.h"
21 
22 namespace OHOS {
23 namespace AppExecFwk {
SharedBundleInstaller(const InstallParam & installParam,const Constants::AppType appType)24 SharedBundleInstaller::SharedBundleInstaller(const InstallParam &installParam, const Constants::AppType appType)
25     : installParam_(installParam), appType_(appType)
26 {
27     APP_LOGI("shared bundle installer instance is created");
28 }
29 
~SharedBundleInstaller()30 SharedBundleInstaller::~SharedBundleInstaller()
31 {
32     APP_LOGI("shared bundle installer instance is destroyed");
33 }
34 
ParseFiles()35 ErrCode SharedBundleInstaller::ParseFiles()
36 {
37     ErrCode result = ERR_OK;
38     if (installParam_.sharedBundleDirPaths.empty()) {
39         APP_LOGI("sharedBundleDirPaths is empty");
40         return result;
41     }
42 
43     InstallCheckParam checkParam;
44     checkParam.isPreInstallApp = installParam_.isPreInstallApp;
45     checkParam.crowdtestDeadline = installParam_.crowdtestDeadline;
46     checkParam.appType = appType_;
47     checkParam.removable = installParam_.removable;
48     checkParam.installBundlePermissionStatus = installParam_.installBundlePermissionStatus;
49     checkParam.installEnterpriseBundlePermissionStatus = installParam_.installEnterpriseBundlePermissionStatus;
50     checkParam.installEtpNormalBundlePermissionStatus = installParam_.installEtpNormalBundlePermissionStatus;
51     checkParam.installEtpMdmBundlePermissionStatus = installParam_.installEtpMdmBundlePermissionStatus;
52     checkParam.isCallByShell = installParam_.isCallByShell;
53 
54     for (const auto &path : installParam_.sharedBundleDirPaths) {
55         auto installer = std::make_shared<InnerSharedBundleInstaller>(path);
56         result = installer->ParseFiles(checkParam);
57         CHECK_RESULT(result, "parse file failed %{public}d");
58         if (innerInstallers_.find(installer->GetBundleName()) != innerInstallers_.end()) {
59             APP_LOGW("sharedBundleDirPaths does not support that different paths contain hsp of same bundleName");
60             continue;
61         }
62         innerInstallers_.emplace(installer->GetBundleName(), installer);
63     }
64 
65     APP_LOGI("parse shared bundles successfully");
66     return result;
67 }
68 
CheckDependency(const InnerBundleInfo & innerBundleInfo) const69 bool SharedBundleInstaller::CheckDependency(const InnerBundleInfo &innerBundleInfo) const
70 {
71     if (innerBundleInfo.GetDependencies().empty()) {
72         APP_LOGD("dependencies of %{public}s is empty", innerBundleInfo.GetBundleName().c_str());
73         return true;
74     }
75 
76     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
77     if (dataMgr == nullptr) {
78         APP_LOGE("Get dataMgr shared_ptr nullptr");
79         return false;
80     }
81 
82     for (const auto &dependency : innerBundleInfo.GetDependencies()) {
83         if (dependency.bundleName.empty() || dependency.bundleName == innerBundleInfo.GetBundleName()) {
84             APP_LOGD("inner-app dependency: %{public}s", GetJsonStrFromInfo(dependency).c_str());
85             continue;
86         }
87 
88         auto iter = innerInstallers_.find(dependency.bundleName);
89         if (iter != innerInstallers_.end() && iter->second->CheckDependency(dependency)) {
90             APP_LOGD("dependency found in installing shared bundles: %{public}s",
91                 GetJsonStrFromInfo(dependency).c_str());
92             continue;
93         }
94 
95         if (FindDependencyInInstalledBundles(dependency)) {
96             APP_LOGD("dependency found in installed shared bundles: %{public}s",
97                 GetJsonStrFromInfo(dependency).c_str());
98             continue;
99         }
100 
101         APP_LOGE("dependency not found: %{public}s", GetJsonStrFromInfo(dependency).c_str());
102         return false;
103     }
104 
105     APP_LOGD("dependencies are satisfied");
106     return true;
107 }
108 
Install(const EventInfo & eventTemplate)109 ErrCode SharedBundleInstaller::Install(const EventInfo &eventTemplate)
110 {
111     if (!NeedToInstall()) {
112         APP_LOGI("do not need to install");
113         return ERR_OK;
114     }
115 
116     std::vector<std::string> processedBundles;
117     ScopeGuard installGuard([this, &processedBundles] {
118         APP_LOGE("install shared bundles failed, rollbacking:%{public}s", GetJsonStrFromInfo(processedBundles).c_str());
119         for (auto iter = processedBundles.crbegin(); iter != processedBundles.crend(); ++iter) {
120             auto installer = innerInstallers_.find(*iter);
121             if (installer != innerInstallers_.end()) {
122                 installer->second->RollBack();
123             } else {
124                 APP_LOGE("rollback failed : %{public}s", iter->c_str());
125             }
126         }
127     });
128 
129     ErrCode result = ERR_OK;
130     for (auto installer : innerInstallers_) {
131         result = installer.second->Install(installParam_);
132         processedBundles.emplace_back(installer.first);
133         CHECK_RESULT(result, "install shared bundle failed %{public}d");
134     }
135 
136     installGuard.Dismiss();
137     SendBundleSystemEvent(eventTemplate);
138     APP_LOGD("install shared bundles success");
139     return result;
140 }
141 
FindDependencyInInstalledBundles(const Dependency & dependency) const142 bool SharedBundleInstaller::FindDependencyInInstalledBundles(const Dependency &dependency) const
143 {
144     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
145     if (dataMgr == nullptr) {
146         APP_LOGE("Get dataMgr shared_ptr nullptr");
147         return false;
148     }
149 
150     InnerBundleInfo bundleInfo;
151     bool isBundleExist = dataMgr->FetchInnerBundleInfo(dependency.bundleName, bundleInfo);
152     if (!isBundleExist || bundleInfo.GetApplicationBundleType() != BundleType::SHARED) {
153         APP_LOGE("the shared bundle (%{public}s) is not installed", dependency.bundleName.c_str());
154         return false;
155     }
156 
157     BaseSharedBundleInfo sharedBundle;
158     bool isModuleExist = bundleInfo.GetMaxVerBaseSharedBundleInfo(dependency.moduleName, sharedBundle);
159     if (isModuleExist && dependency.versionCode <= sharedBundle.versionCode) {
160         return true;
161     }
162 
163     APP_LOGE("the module or version not satisfied : %{public}s", GetJsonStrFromInfo(dependency).c_str());
164     return false;
165 }
166 
SendBundleSystemEvent(const EventInfo & eventTemplate)167 void SharedBundleInstaller::SendBundleSystemEvent(const EventInfo &eventTemplate)
168 {
169     EventInfo commonEventInfo = eventTemplate;
170     commonEventInfo.isPreInstallApp = installParam_.isPreInstallApp;
171     commonEventInfo.errCode = ERR_OK;
172     commonEventInfo.isFreeInstallMode = (installParam_.installFlag == InstallFlag::FREE_INSTALL);
173     GetCallingEventInfo(commonEventInfo);
174 
175     for (auto installer : innerInstallers_) {
176         installer.second->SendBundleSystemEvent(commonEventInfo);
177     }
178 }
179 
GetCallingEventInfo(EventInfo & eventInfo)180 void SharedBundleInstaller::GetCallingEventInfo(EventInfo &eventInfo)
181 {
182     APP_LOGD("GetCallingEventInfo start, bundleName:%{public}s", eventInfo.callingBundleName.c_str());
183     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
184     if (dataMgr == nullptr) {
185         APP_LOGE("Get dataMgr shared_ptr nullptr");
186         return;
187     }
188     if (!dataMgr->GetBundleNameForUid(eventInfo.callingUid, eventInfo.callingBundleName)) {
189         APP_LOGW("CallingUid %{public}d is not hap, no bundleName", eventInfo.callingUid);
190         eventInfo.callingBundleName = Constants::EMPTY_STRING;
191         return;
192     }
193 
194     BundleInfo bundleInfo;
195     if (!dataMgr->GetBundleInfo(eventInfo.callingBundleName, BundleFlag::GET_BUNDLE_DEFAULT, bundleInfo,
196         eventInfo.callingUid / Constants::BASE_USER_RANGE)) {
197         APP_LOGE("GetBundleInfo failed, bundleName: %{public}s", eventInfo.callingBundleName.c_str());
198         return;
199     }
200     eventInfo.callingAppId = bundleInfo.appId;
201 }
202 }  // namespace AppExecFwk
203 }  // namespace OHOS
204