1 /*
2  * Copyright (c) 2021-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 "bundle_installer.h"
17 
18 #include <cinttypes>
19 
20 #include "app_log_tag_wrapper.h"
21 #include "bundle_mgr_service.h"
22 
23 namespace OHOS {
24 namespace AppExecFwk {
BundleInstaller(const int64_t installerId, const sptr<IStatusReceiver> &statusReceiver)25 BundleInstaller::BundleInstaller(const int64_t installerId, const sptr<IStatusReceiver> &statusReceiver)
26     : installerId_(installerId), statusReceiver_(statusReceiver)
27 {
28     LOG_NOFUNC_I(BMS_TAG_INSTALLER, "create bundle installer instance id:%{public}" PRId64 "", installerId_);
29 }
30 
~BundleInstaller()31 BundleInstaller::~BundleInstaller()
32 {
33     LOG_NOFUNC_I(BMS_TAG_INSTALLER, "destroy installer id:%{public}" PRId64 "", installerId_);
34 }
35 
Install(const std::string &bundleFilePath, const InstallParam &installParam)36 void BundleInstaller::Install(const std::string &bundleFilePath, const InstallParam &installParam)
37 {
38     ErrCode resultCode = ERR_OK;
39     if (installParam.userId == Constants::ALL_USERID) {
40         auto userInstallParam = installParam;
41         userInstallParam.allUser = true;
42         for (auto userId : GetExistsCommonUserIds()) {
43             userInstallParam.userId = userId;
44             userInstallParam.installFlag = InstallFlag::REPLACE_EXISTING;
45             resultCode = InstallBundle(
46                 bundleFilePath, userInstallParam, Constants::AppType::THIRD_PARTY_APP);
47             ResetInstallProperties();
48         }
49 
50         NotifyAllBundleStatus();
51     } else {
52         resultCode = InstallBundle(
53             bundleFilePath, installParam, Constants::AppType::THIRD_PARTY_APP);
54         InstallDriverForAllUsers(bundleFilePath, installParam);
55     }
56     std::string resultMsg = GetCheckResultMsg();
57     SetCheckResultMsg("");
58     if (statusReceiver_ != nullptr) {
59         statusReceiver_->OnFinished(resultCode, resultMsg);
60     }
61 }
62 
Recover(const std::string &bundleName, const InstallParam &installParam)63 void BundleInstaller::Recover(const std::string &bundleName, const InstallParam &installParam)
64 {
65     ErrCode resultCode = ERR_OK;
66     if (installParam.userId == Constants::ALL_USERID) {
67         auto userInstallParam = installParam;
68         for (auto userId : GetExistsCommonUserIds()) {
69             userInstallParam.userId = userId;
70             userInstallParam.installFlag = InstallFlag::REPLACE_EXISTING;
71             resultCode = BaseBundleInstaller::Recover(bundleName, userInstallParam);
72             ResetInstallProperties();
73         }
74     } else {
75         resultCode = BaseBundleInstaller::Recover(bundleName, installParam);
76         RecoverDriverForAllUsers(bundleName, installParam);
77     }
78 
79     if (statusReceiver_ != nullptr) {
80         statusReceiver_->OnFinished(resultCode, "");
81     }
82 }
83 
Install(const std::vector<std::string> &bundleFilePaths, const InstallParam &installParam)84 void BundleInstaller::Install(const std::vector<std::string> &bundleFilePaths, const InstallParam &installParam)
85 {
86     ErrCode resultCode = ERR_OK;
87     if (installParam.userId == Constants::ALL_USERID) {
88         auto userInstallParam = installParam;
89         userInstallParam.allUser = true;
90         for (auto userId : GetExistsCommonUserIds()) {
91             userInstallParam.userId = userId;
92             userInstallParam.installFlag = InstallFlag::REPLACE_EXISTING;
93             resultCode = InstallBundle(
94                 bundleFilePaths, userInstallParam, Constants::AppType::THIRD_PARTY_APP);
95             ResetInstallProperties();
96         }
97 
98         NotifyAllBundleStatus();
99     } else {
100         resultCode = InstallBundle(bundleFilePaths, installParam, Constants::AppType::THIRD_PARTY_APP);
101         InstallDriverForAllUsers(bundleFilePaths, installParam);
102     }
103     std::string resultMsg = GetCheckResultMsg();
104     SetCheckResultMsg("");
105     if (statusReceiver_ != nullptr) {
106         statusReceiver_->OnFinished(resultCode, resultMsg);
107     }
108 }
109 
InstallByBundleName(const std::string &bundleName, const InstallParam &installParam)110 void BundleInstaller::InstallByBundleName(const std::string &bundleName, const InstallParam &installParam)
111 {
112     ErrCode resultCode = InstallBundleByBundleName(bundleName, installParam);
113     if (statusReceiver_ != nullptr) {
114         statusReceiver_->OnFinished(resultCode, "");
115     }
116 }
117 
Uninstall(const std::string &bundleName, const InstallParam &installParam)118 void BundleInstaller::Uninstall(const std::string &bundleName, const InstallParam &installParam)
119 {
120     ErrCode resultCode = ERR_OK;
121     if (installParam.userId == Constants::ALL_USERID ||
122         (!installParam.isRemoveUser && HasDriverExtensionAbility(bundleName))) {
123         std::vector<ErrCode> errCode;
124         auto userInstallParam = installParam;
125         for (auto userId : GetExistsCommonUserIds()) {
126             userInstallParam.userId = userId;
127             resultCode = UninstallBundle(bundleName, userInstallParam);
128             errCode.push_back(resultCode);
129             ResetInstallProperties();
130         }
131         if (std::find(errCode.begin(), errCode.end(), ERR_OK) != errCode.end()) {
132             for (const auto &err : errCode) {
133                 if (!(err == ERR_APPEXECFWK_UNINSTALL_MISSING_INSTALLED_BUNDLE ||
134                     err == ERR_APPEXECFWK_USER_NOT_INSTALL_HAP || err == ERR_OK)) {
135                     resultCode = err;
136                     break;
137                 }
138                 resultCode = ERR_OK;
139             }
140         } else {
141             resultCode = (errCode.size() > 0) ? errCode[0] : ERR_OK;
142         }
143     } else {
144         resultCode = UninstallBundle(bundleName, installParam);
145     }
146 
147     if (statusReceiver_ != nullptr) {
148         statusReceiver_->OnFinished(resultCode, "");
149     }
150 }
151 
Uninstall(const UninstallParam &uninstallParam)152 void BundleInstaller::Uninstall(const UninstallParam &uninstallParam)
153 {
154     ErrCode resultCode = ERR_OK;
155     resultCode = UninstallBundleByUninstallParam(uninstallParam);
156     if (statusReceiver_ != nullptr) {
157         statusReceiver_->OnFinished(resultCode, "");
158     }
159 }
160 
Uninstall( const std::string &bundleName, const std::string &modulePackage, const InstallParam &installParam)161 void BundleInstaller::Uninstall(
162     const std::string &bundleName, const std::string &modulePackage, const InstallParam &installParam)
163 {
164     ErrCode resultCode = ERR_OK;
165     if (installParam.userId == Constants::ALL_USERID || HasDriverExtensionAbility(bundleName)) {
166         std::vector<ErrCode> errCode;
167         auto userInstallParam = installParam;
168         for (auto userId : GetExistsCommonUserIds()) {
169             userInstallParam.userId = userId;
170             resultCode = UninstallBundle(bundleName, modulePackage, userInstallParam);
171             errCode.push_back(resultCode);
172             ResetInstallProperties();
173         }
174         if (std::find(errCode.begin(), errCode.end(), ERR_OK) != errCode.end()) {
175             for (const auto &err : errCode) {
176                 if (!(err == ERR_APPEXECFWK_UNINSTALL_MISSING_INSTALLED_BUNDLE ||
177                     err == ERR_APPEXECFWK_UNINSTALL_MISSING_INSTALLED_MODULE ||
178                     err == ERR_APPEXECFWK_USER_NOT_INSTALL_HAP || err == ERR_OK)) {
179                     resultCode = err;
180                     break;
181                 }
182                 resultCode = ERR_OK;
183             }
184         } else {
185             resultCode = (errCode.size() > 0) ? errCode[0] : ERR_OK;
186         }
187     } else {
188         resultCode = UninstallBundle(bundleName, modulePackage, installParam);
189     }
190 
191     if (statusReceiver_ != nullptr) {
192         statusReceiver_->OnFinished(resultCode, "");
193     }
194 }
195 
UpdateInstallerState(const InstallerState state)196 void BundleInstaller::UpdateInstallerState(const InstallerState state)
197 {
198     LOG_I(BMS_TAG_INSTALLER, "state: %{public}d", static_cast<int32_t>(state));
199     SetInstallerState(state);
200     if (statusReceiver_) {
201         statusReceiver_->OnStatusNotify(static_cast<int>(state));
202     }
203 }
204 
GetExistsCommonUserIds()205 std::set<int32_t> BundleInstaller::GetExistsCommonUserIds()
206 {
207     std::set<int32_t> userIds;
208     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
209     if (dataMgr == nullptr) {
210         LOG_E(BMS_TAG_INSTALLER, "Get dataMgr shared_ptr nullptr");
211         return userIds;
212     }
213 
214     for (auto userId : dataMgr->GetAllUser()) {
215         if (userId >= Constants::START_USERID) {
216             userIds.insert(userId);
217         }
218     }
219     return userIds;
220 }
221 
InstallDriverForAllUsers(const std::string &bundleFilePath, const InstallParam &installParam)222 void BundleInstaller::InstallDriverForAllUsers(const std::string &bundleFilePath, const InstallParam &installParam)
223 {
224     std::vector<std::string> bundleFilePaths { bundleFilePath };
225     InstallDriverForAllUsers(bundleFilePaths, installParam);
226 }
227 
InstallDriverForAllUsers(const std::vector<std::string> &bundleFilePaths, const InstallParam &installParam)228 void BundleInstaller::InstallDriverForAllUsers(const std::vector<std::string> &bundleFilePaths,
229     const InstallParam &installParam)
230 {
231     std::string bundleName = GetCurrentBundleName();
232     if (!HasDriverExtensionAbility(bundleName)) {
233         APP_LOGD("bundle %{public}s has no driver extension ability", bundleName.c_str());
234         return;
235     }
236     APP_LOGI("bundle %{public}s has driver extension ability, need to install for all users", bundleName.c_str());
237     ResetInstallProperties();
238     auto userInstallParam = installParam;
239     userInstallParam.allUser = true;
240     for (auto userId : GetExistsCommonUserIds()) {
241         if (userId == installParam.userId) {
242             continue;
243         }
244         userInstallParam.userId = userId;
245         userInstallParam.installFlag = InstallFlag::REPLACE_EXISTING;
246         ErrCode resultCode = InstallBundle(
247             bundleFilePaths, userInstallParam, Constants::AppType::THIRD_PARTY_APP);
248         ResetInstallProperties();
249         if (resultCode != ERR_OK) {
250             APP_LOGE("install driver for user %{public}d failed, resultCode: %{public}d", userId, resultCode);
251         }
252     }
253     NotifyAllBundleStatus();
254 }
255 
RecoverDriverForAllUsers(const std::string &bundleName, const InstallParam &installParam)256 void BundleInstaller::RecoverDriverForAllUsers(const std::string &bundleName, const InstallParam &installParam)
257 {
258     if (!HasDriverExtensionAbility(bundleName)) {
259         APP_LOGD("bundle %{public}s has no driver extension ability", bundleName.c_str());
260         return;
261     }
262     APP_LOGI("bundle %{public}s has driver extension ability, need to recover for all users", bundleName.c_str());
263     ResetInstallProperties();
264     auto userInstallParam = installParam;
265     for (auto userId : GetExistsCommonUserIds()) {
266         if (userId == installParam.userId) {
267             continue;
268         }
269         userInstallParam.userId = userId;
270         userInstallParam.installFlag = InstallFlag::REPLACE_EXISTING;
271         ErrCode resultCode = BaseBundleInstaller::Recover(bundleName, userInstallParam);
272         ResetInstallProperties();
273         if (resultCode != ERR_OK) {
274             APP_LOGE("recover driver for user %{public}d failed, resultCode: %{public}d", userId, resultCode);
275         }
276     }
277 }
278 
UninstallAndRecover(const std::string &bundleName, const InstallParam &installParam)279 void BundleInstaller::UninstallAndRecover(const std::string &bundleName, const InstallParam &installParam)
280 {
281     ErrCode resultCode = ERR_OK;
282     std::vector<ErrCode> errCode;
283     auto userInstallParam = installParam;
284     std::vector<int32_t> userIds;
285     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
286     if (dataMgr != nullptr) {
287         userIds = dataMgr->GetUserIds(bundleName);
288     }
289     for (auto userId : userIds) {
290         userInstallParam.userId = userId;
291         userInstallParam.SetIsUninstallAndRecover(true);
292         resultCode = UninstallBundle(bundleName, userInstallParam);
293         errCode.push_back(resultCode);
294         ResetInstallProperties();
295     }
296     for (auto userId : userIds) {
297         userInstallParam.userId = userId;
298         userInstallParam.installFlag = InstallFlag::REPLACE_EXISTING;
299         resultCode = BaseBundleInstaller::Recover(bundleName, userInstallParam);
300         errCode.push_back(resultCode);
301         ResetInstallProperties();
302     }
303 
304     if (std::find(errCode.begin(), errCode.end(), ERR_OK) != errCode.end()) {
305         for (const auto &err : errCode) {
306             if (err != ERR_OK) {
307                 resultCode = err;
308                 break;
309             }
310             resultCode = ERR_OK;
311         }
312     } else {
313         resultCode = (errCode.size() > 0) ? errCode[0] : ERR_APPEXECFWK_UNINSTALL_MISSING_INSTALLED_BUNDLE;
314     }
315     if (statusReceiver_ != nullptr) {
316         statusReceiver_->OnFinished(resultCode, "");
317     }
318 }
319 }  // namespace AppExecFwk
320 }  // namespace OHOS