1 /*
2 * Copyright (c) 2021 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_manager.h"
17
18 #include <cinttypes>
19
20 #include "appexecfwk_errors.h"
21 #include "app_log_wrapper.h"
22 #include "bundle_mgr_service.h"
23 #include "datetime_ex.h"
24 #include "xcollie_helper.h"
25
26 namespace OHOS {
27 namespace AppExecFwk {
28 namespace {
29 const std::string ADD_INSTALLER_FAIL = "fail to add installer in bundle installer manager";
30 const std::string INSTALL_TASK = "Install_Task";
31 const std::string UNINSTALL_TASK = "Uninstall_Task";
32 const std::string RECOVER_TASK = "Recover_Task";
33 const unsigned int TIME_OUT_SECONDS = 60 * 5;
34 }
35
BundleInstallerManager(const std::shared_ptr<EventRunner> & runner)36 BundleInstallerManager::BundleInstallerManager(const std::shared_ptr<EventRunner> &runner) : EventHandler(runner)
37 {
38 APP_LOGI("create bundle installer manager instance");
39 }
40
~BundleInstallerManager()41 BundleInstallerManager::~BundleInstallerManager()
42 {
43 APP_LOGI("destroy bundle installer manager instance");
44 }
45
ProcessEvent(const InnerEvent::Pointer & event)46 void BundleInstallerManager::ProcessEvent(const InnerEvent::Pointer &event)
47 {
48 APP_LOGD("process event : %{public}u", event->GetInnerEventId());
49 switch (event->GetInnerEventId()) {
50 case REMOVE_BUNDLE_INSTALLER:
51 RemoveInstaller(event->GetParam());
52 break;
53 default:
54 APP_LOGW("the eventId is not supported");
55 }
56 }
57
CreateInstallTask(const std::string & bundleFilePath,const InstallParam & installParam,const sptr<IStatusReceiver> & statusReceiver)58 void BundleInstallerManager::CreateInstallTask(
59 const std::string &bundleFilePath, const InstallParam &installParam, const sptr<IStatusReceiver> &statusReceiver)
60 {
61 auto installer = CreateInstaller(statusReceiver);
62 if (installer == nullptr) {
63 APP_LOGE("create installer failed");
64 return;
65 }
66 auto task = [installer, bundleFilePath, installParam] {
67 int timerId = XCollieHelper::SetTimer(INSTALL_TASK, TIME_OUT_SECONDS, nullptr, nullptr);
68 installer->Install(bundleFilePath, installParam);
69 XCollieHelper::CancelTimer(timerId);
70 };
71 AddTask(task);
72 }
73
CreateRecoverTask(const std::string & bundleName,const InstallParam & installParam,const sptr<IStatusReceiver> & statusReceiver)74 void BundleInstallerManager::CreateRecoverTask(
75 const std::string &bundleName, const InstallParam &installParam, const sptr<IStatusReceiver> &statusReceiver)
76 {
77 auto installer = CreateInstaller(statusReceiver);
78 if (installer == nullptr) {
79 APP_LOGE("create installer failed");
80 return;
81 }
82 auto task = [installer, bundleName, installParam] {
83 int timerId = XCollieHelper::SetTimer(RECOVER_TASK, TIME_OUT_SECONDS, nullptr, nullptr);
84 installer->Recover(bundleName, installParam);
85 XCollieHelper::CancelTimer(timerId);
86 };
87 AddTask(task);
88 }
89
CreateInstallTask(const std::vector<std::string> & bundleFilePaths,const InstallParam & installParam,const sptr<IStatusReceiver> & statusReceiver)90 void BundleInstallerManager::CreateInstallTask(const std::vector<std::string> &bundleFilePaths,
91 const InstallParam &installParam, const sptr<IStatusReceiver> &statusReceiver)
92 {
93 auto installer = CreateInstaller(statusReceiver);
94 if (installer == nullptr) {
95 APP_LOGE("create installer failed");
96 return;
97 }
98 auto task = [installer, bundleFilePaths, installParam] {
99 int timerId = XCollieHelper::SetTimer(INSTALL_TASK, TIME_OUT_SECONDS, nullptr, nullptr);
100 installer->Install(bundleFilePaths, installParam);
101 XCollieHelper::CancelTimer(timerId);
102 };
103 AddTask(task);
104 }
105
CreateInstallByBundleNameTask(const std::string & bundleName,const InstallParam & installParam,const sptr<IStatusReceiver> & statusReceiver)106 void BundleInstallerManager::CreateInstallByBundleNameTask(const std::string &bundleName,
107 const InstallParam &installParam, const sptr<IStatusReceiver> &statusReceiver)
108 {
109 auto installer = CreateInstaller(statusReceiver);
110 if (installer == nullptr) {
111 APP_LOGE("create installer failed");
112 return;
113 }
114
115 auto task = [installer, bundleName, installParam] {
116 int timerId = XCollieHelper::SetTimer(INSTALL_TASK, TIME_OUT_SECONDS, nullptr, nullptr);
117 installer->InstallByBundleName(bundleName, installParam);
118 XCollieHelper::CancelTimer(timerId);
119 };
120 AddTask(task);
121 }
122
CreateUninstallTask(const std::string & bundleName,const InstallParam & installParam,const sptr<IStatusReceiver> & statusReceiver)123 void BundleInstallerManager::CreateUninstallTask(
124 const std::string &bundleName, const InstallParam &installParam, const sptr<IStatusReceiver> &statusReceiver)
125 {
126 auto installer = CreateInstaller(statusReceiver);
127 if (installer == nullptr) {
128 APP_LOGE("create installer failed");
129 return;
130 }
131 auto task = [installer, bundleName, installParam] {
132 int timerId = XCollieHelper::SetTimer(UNINSTALL_TASK, TIME_OUT_SECONDS, nullptr, nullptr);
133 installer->Uninstall(bundleName, installParam);
134 XCollieHelper::CancelTimer(timerId);
135 };
136 AddTask(task);
137 }
138
CreateUninstallTask(const std::string & bundleName,const std::string & modulePackage,const InstallParam & installParam,const sptr<IStatusReceiver> & statusReceiver)139 void BundleInstallerManager::CreateUninstallTask(const std::string &bundleName, const std::string &modulePackage,
140 const InstallParam &installParam, const sptr<IStatusReceiver> &statusReceiver)
141 {
142 auto installer = CreateInstaller(statusReceiver);
143 if (installer == nullptr) {
144 APP_LOGE("create installer failed");
145 return;
146 }
147 auto task = [installer, bundleName, modulePackage, installParam] {
148 int timerId = XCollieHelper::SetTimer(UNINSTALL_TASK, TIME_OUT_SECONDS, nullptr, nullptr);
149 installer->Uninstall(bundleName, modulePackage, installParam);
150 XCollieHelper::CancelTimer(timerId);
151 };
152 AddTask(task);
153 }
154
CreateInstaller(const sptr<IStatusReceiver> & statusReceiver)155 std::shared_ptr<BundleInstaller> BundleInstallerManager::CreateInstaller(const sptr<IStatusReceiver> &statusReceiver)
156 {
157 int64_t installerId = GetMicroTickCount();
158 auto installer = std::make_shared<BundleInstaller>(installerId, shared_from_this(), statusReceiver);
159 bool isSuccess = false;
160 {
161 std::lock_guard<std::mutex> lock(mutex_);
162 auto result = installers_.try_emplace(installer->GetInstallerId(), installer);
163 isSuccess = result.second;
164 }
165 if (isSuccess) {
166 APP_LOGD("add the specific %{public}" PRId64 " installer", installerId);
167 } else {
168 APP_LOGE("fail to add bundle installer");
169 installer.reset();
170 statusReceiver->OnFinished(ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR, ADD_INSTALLER_FAIL);
171 }
172 return installer;
173 }
174
RemoveInstaller(const int64_t installerId)175 void BundleInstallerManager::RemoveInstaller(const int64_t installerId)
176 {
177 APP_LOGD("start to remove installer the specific %{public}" PRId64 " installer", installerId);
178 std::lock_guard<std::mutex> lock(mutex_);
179 if (installers_.erase(installerId) > 0) {
180 APP_LOGD("erase the specific %{public}" PRId64 " installer", installerId);
181 }
182 }
183
AddTask(const ThreadPoolTask & task)184 void BundleInstallerManager::AddTask(const ThreadPoolTask &task)
185 {
186 auto bundleMgrService = DelayedSingleton<BundleMgrService>::GetInstance();
187 if (bundleMgrService == nullptr) {
188 APP_LOGE("bundleMgrService is nullptr");
189 return;
190 }
191
192 ThreadPool &installersPool = bundleMgrService->GetThreadPool();
193 installersPool.AddTask(task);
194 }
195 } // namespace AppExecFwk
196 } // namespace OHOS