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     }
55     std::string resultMsg = GetCheckResultMsg();
56     SetCheckResultMsg("");
57     if (statusReceiver_ != nullptr) {
58         statusReceiver_->OnFinished(resultCode, resultMsg);
59     }
60 }
61 
Recover(const std::string & bundleName,const InstallParam & installParam)62 void BundleInstaller::Recover(const std::string &bundleName, const InstallParam &installParam)
63 {
64     ErrCode resultCode = ERR_OK;
65     if (installParam.userId == Constants::ALL_USERID) {
66         auto userInstallParam = installParam;
67         for (auto userId : GetExistsCommonUserIds()) {
68             userInstallParam.userId = userId;
69             userInstallParam.installFlag = InstallFlag::REPLACE_EXISTING;
70             resultCode = BaseBundleInstaller::Recover(bundleName, userInstallParam);
71             ResetInstallProperties();
72         }
73     } else {
74         resultCode = BaseBundleInstaller::Recover(bundleName, installParam);
75     }
76 
77     if (statusReceiver_ != nullptr) {
78         statusReceiver_->OnFinished(resultCode, "");
79     }
80 }
81 
Install(const std::vector<std::string> & bundleFilePaths,const InstallParam & installParam)82 void BundleInstaller::Install(const std::vector<std::string> &bundleFilePaths, const InstallParam &installParam)
83 {
84     ErrCode resultCode = ERR_OK;
85     if (installParam.userId == Constants::ALL_USERID) {
86         auto userInstallParam = installParam;
87         userInstallParam.allUser = true;
88         for (auto userId : GetExistsCommonUserIds()) {
89             userInstallParam.userId = userId;
90             userInstallParam.installFlag = InstallFlag::REPLACE_EXISTING;
91             resultCode = InstallBundle(
92                 bundleFilePaths, userInstallParam, Constants::AppType::THIRD_PARTY_APP);
93             ResetInstallProperties();
94         }
95 
96         NotifyAllBundleStatus();
97     } else {
98         resultCode = InstallBundle(bundleFilePaths, installParam, Constants::AppType::THIRD_PARTY_APP);
99     }
100     std::string resultMsg = GetCheckResultMsg();
101     SetCheckResultMsg("");
102     if (statusReceiver_ != nullptr) {
103         statusReceiver_->OnFinished(resultCode, resultMsg);
104     }
105 }
106 
InstallByBundleName(const std::string & bundleName,const InstallParam & installParam)107 void BundleInstaller::InstallByBundleName(const std::string &bundleName, const InstallParam &installParam)
108 {
109     ErrCode resultCode = InstallBundleByBundleName(bundleName, installParam);
110     if (statusReceiver_ != nullptr) {
111         statusReceiver_->OnFinished(resultCode, "");
112     }
113 }
114 
Uninstall(const std::string & bundleName,const InstallParam & installParam)115 void BundleInstaller::Uninstall(const std::string &bundleName, const InstallParam &installParam)
116 {
117     ErrCode resultCode = ERR_OK;
118     if (installParam.userId == Constants::ALL_USERID) {
119         std::vector<ErrCode> errCode;
120         auto userInstallParam = installParam;
121         for (auto userId : GetExistsCommonUserIds()) {
122             userInstallParam.userId = userId;
123             resultCode = UninstallBundle(bundleName, userInstallParam);
124             errCode.push_back(resultCode);
125             ResetInstallProperties();
126         }
127         if (std::find(errCode.begin(), errCode.end(), ERR_OK) != errCode.end()) {
128             for (const auto &err : errCode) {
129                 if (!(err == ERR_APPEXECFWK_UNINSTALL_MISSING_INSTALLED_BUNDLE ||
130                     err == ERR_APPEXECFWK_USER_NOT_INSTALL_HAP || err == ERR_OK)) {
131                     resultCode = err;
132                     break;
133                 }
134                 resultCode = ERR_OK;
135             }
136         } else {
137             resultCode = (errCode.size() > 0) ? errCode[0] : ERR_OK;
138         }
139     } else {
140         resultCode = UninstallBundle(bundleName, installParam);
141     }
142 
143     if (statusReceiver_ != nullptr) {
144         statusReceiver_->OnFinished(resultCode, "");
145     }
146 }
147 
Uninstall(const UninstallParam & uninstallParam)148 void BundleInstaller::Uninstall(const UninstallParam &uninstallParam)
149 {
150     ErrCode resultCode = ERR_OK;
151     resultCode = UninstallBundleByUninstallParam(uninstallParam);
152     if (statusReceiver_ != nullptr) {
153         statusReceiver_->OnFinished(resultCode, "");
154     }
155 }
156 
Uninstall(const std::string & bundleName,const std::string & modulePackage,const InstallParam & installParam)157 void BundleInstaller::Uninstall(
158     const std::string &bundleName, const std::string &modulePackage, const InstallParam &installParam)
159 {
160     ErrCode resultCode = ERR_OK;
161     if (installParam.userId == Constants::ALL_USERID) {
162         std::vector<ErrCode> errCode;
163         auto userInstallParam = installParam;
164         for (auto userId : GetExistsCommonUserIds()) {
165             userInstallParam.userId = userId;
166             resultCode = UninstallBundle(bundleName, modulePackage, userInstallParam);
167             errCode.push_back(resultCode);
168             ResetInstallProperties();
169         }
170         if (std::find(errCode.begin(), errCode.end(), ERR_OK) != errCode.end()) {
171             for (const auto &err : errCode) {
172                 if (!(err == ERR_APPEXECFWK_UNINSTALL_MISSING_INSTALLED_BUNDLE ||
173                     err == ERR_APPEXECFWK_UNINSTALL_MISSING_INSTALLED_MODULE ||
174                     err == ERR_APPEXECFWK_USER_NOT_INSTALL_HAP || err == ERR_OK)) {
175                     resultCode = err;
176                     break;
177                 }
178                 resultCode = ERR_OK;
179             }
180         } else {
181             resultCode = (errCode.size() > 0) ? errCode[0] : ERR_OK;
182         }
183     } else {
184         resultCode = UninstallBundle(bundleName, modulePackage, installParam);
185     }
186 
187     if (statusReceiver_ != nullptr) {
188         statusReceiver_->OnFinished(resultCode, "");
189     }
190 }
191 
UpdateInstallerState(const InstallerState state)192 void BundleInstaller::UpdateInstallerState(const InstallerState state)
193 {
194     LOG_D(BMS_TAG_INSTALLER, "state: %{public}d", state);
195     SetInstallerState(state);
196     if (statusReceiver_) {
197         statusReceiver_->OnStatusNotify(static_cast<int>(state));
198     }
199 }
200 
GetExistsCommonUserIds()201 std::set<int32_t> BundleInstaller::GetExistsCommonUserIds()
202 {
203     std::set<int32_t> userIds;
204     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
205     if (dataMgr == nullptr) {
206         LOG_E(BMS_TAG_INSTALLER, "Get dataMgr shared_ptr nullptr");
207         return userIds;
208     }
209 
210     for (auto userId : dataMgr->GetAllUser()) {
211         if (userId >= Constants::START_USERID) {
212             userIds.insert(userId);
213         }
214     }
215     return userIds;
216 }
217 
UninstallAndRecover(const std::string & bundleName,const InstallParam & installParam)218 void BundleInstaller::UninstallAndRecover(const std::string &bundleName, const InstallParam &installParam)
219 {
220     ErrCode resultCode = ERR_OK;
221     std::vector<ErrCode> errCode;
222     auto userInstallParam = installParam;
223     std::vector<int32_t> userIds;
224     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
225     if (dataMgr != nullptr) {
226         userIds = dataMgr->GetUserIds(bundleName);
227     }
228     for (auto userId : userIds) {
229         userInstallParam.userId = userId;
230         userInstallParam.SetIsUninstallAndRecover(true);
231         resultCode = UninstallBundle(bundleName, userInstallParam);
232         errCode.push_back(resultCode);
233         ResetInstallProperties();
234     }
235     for (auto userId : userIds) {
236         userInstallParam.userId = userId;
237         userInstallParam.installFlag = InstallFlag::REPLACE_EXISTING;
238         resultCode = BaseBundleInstaller::Recover(bundleName, userInstallParam);
239         errCode.push_back(resultCode);
240         ResetInstallProperties();
241     }
242 
243     if (std::find(errCode.begin(), errCode.end(), ERR_OK) != errCode.end()) {
244         for (const auto &err : errCode) {
245             if (err != ERR_OK) {
246                 resultCode = err;
247                 break;
248             }
249             resultCode = ERR_OK;
250         }
251     } else {
252         resultCode = (errCode.size() > 0) ? errCode[0] : ERR_APPEXECFWK_UNINSTALL_MISSING_INSTALLED_BUNDLE;
253     }
254     if (statusReceiver_ != nullptr) {
255         statusReceiver_->OnFinished(resultCode, "");
256     }
257 }
258 }  // namespace AppExecFwk
259 }  // namespace OHOS