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 "module_update_service.h"
17
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <fcntl.h>
21
22 #include "directory_ex.h"
23 #include "init_reboot.h"
24 #include "ipc_skeleton.h"
25 #include "iservice_registry.h"
26 #include "module_utils.h"
27 #include "json_node.h"
28 #include "log/log.h"
29 #include "module_constants.h"
30 #include "module_file.h"
31 #include "module_error_code.h"
32 #include "module_update_main.h"
33 #include "package/package.h"
34 #include "init_reboot.h"
35 #include "scope_guard.h"
36 #include "system_ability_definition.h"
37 #include "utils.h"
38 #include "unique_fd.h"
39 #ifdef WITH_SELINUX
40 #include <policycoreutils.h>
41 #endif // WITH_SELINUX
42
43 namespace OHOS {
44 namespace SysInstaller {
45 REGISTER_SYSTEM_ABILITY_BY_ID(ModuleUpdateService, MODULE_UPDATE_SERVICE_ID, false)
46
47 using namespace Updater;
48
ModuleUpdateService(int32_t systemAbilityId,bool runOnCreate)49 ModuleUpdateService::ModuleUpdateService(int32_t systemAbilityId, bool runOnCreate)
50 : SystemAbility(systemAbilityId, runOnCreate)
51 {
52 LOG(INFO) << "ModuleUpdateService begin";
53 }
54
~ModuleUpdateService()55 ModuleUpdateService::~ModuleUpdateService()
56 {
57 LOG(INFO) << "ModuleUpdateService end";
58 }
59
InstallModulePackage(const std::string & pkgPath)60 int32_t ModuleUpdateService::InstallModulePackage(const std::string &pkgPath)
61 {
62 LOG(INFO) << "InstallModulePackage " << pkgPath;
63 std::string realPath;
64 if (!CheckFileSuffix(pkgPath, HMP_PACKAGE_SUFFIX) || !PathToRealPath(pkgPath, realPath)) {
65 LOG(ERROR) << "Invalid package path " << pkgPath;
66 return ModuleErrorCode::ERR_INVALID_PATH;
67 }
68 return ModuleUpdateMain::GetInstance().ReallyInstallModulePackage(realPath, nullptr);
69 }
70
UninstallModulePackage(const std::string & hmpName)71 int32_t ModuleUpdateService::UninstallModulePackage(const std::string &hmpName)
72 {
73 LOG(INFO) << "UninstallModulePackage " << hmpName;
74 return ModuleUpdateMain::GetInstance().UninstallModulePackage(hmpName);
75 }
76
GetModulePackageInfo(const std::string & hmpName,std::list<ModulePackageInfo> & modulePackageInfos)77 int32_t ModuleUpdateService::GetModulePackageInfo(const std::string &hmpName,
78 std::list<ModulePackageInfo> &modulePackageInfos)
79 {
80 LOG(INFO) << "GetModulePackageInfo " << hmpName;
81 return ModuleUpdateMain::GetInstance().GetModulePackageInfo(hmpName, modulePackageInfos);
82 }
83
84
ExitModuleUpdate()85 int32_t ModuleUpdateService::ExitModuleUpdate()
86 {
87 LOG(INFO) << "ExitModuleUpdate";
88 ModuleUpdateMain::GetInstance().ExitModuleUpdate();
89 sptr<ISystemAbilityManager> sm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
90 if (sm == nullptr) {
91 LOG(ERROR) << "GetSystemAbilityManager samgr object null!";
92 return 0;
93 }
94 if (sm->UnloadSystemAbility(MODULE_UPDATE_SERVICE_ID) != 0) {
95 LOG(ERROR) << "UnloadSystemAbility error!";
96 }
97 return 0;
98 }
99
GetHmpVersionInfo()100 std::vector<HmpVersionInfo> ModuleUpdateService::GetHmpVersionInfo()
101 {
102 LOG(INFO) << "GetHmpVersionInfo";
103 return ModuleUpdateMain::GetInstance().GetHmpVersionInfo();
104 }
105
StartUpdateHmpPackage(const std::string & path,const sptr<ISysInstallerCallback> & updateCallback)106 int32_t ModuleUpdateService::StartUpdateHmpPackage(const std::string &path,
107 const sptr<ISysInstallerCallback> &updateCallback)
108 {
109 int32_t ret = -1;
110 Timer timer;
111 ON_SCOPE_EXIT(saveResult) {
112 ModuleUpdateMain::GetInstance().SaveInstallerResult(path, ret, std::to_string(ret), timer);
113 if (updateCallback != nullptr) {
114 updateCallback->OnUpgradeProgress(ret == 0 ? UPDATE_STATE_SUCCESSFUL : UPDATE_STATE_FAILED,
115 100, ""); // 100 : 100% percent
116 }
117 };
118 LOG(INFO) << "StartUpdateHmpPackage " << path;
119 if (updateCallback == nullptr) {
120 LOG(ERROR) << "StartUpdateHmpPackage updateCallback null";
121 ret = ModuleErrorCode::ERR_INVALID_PATH;
122 return ret;
123 }
124
125 updateCallback->OnUpgradeProgress(UPDATE_STATE_ONGOING, 0, "");
126 if (VerifyModulePackageSign(path) != 0) {
127 LOG(ERROR) << "Verify sign failed " << path;
128 ret = ModuleErrorCode::ERR_VERIFY_SIGN_FAIL;
129 return ret;
130 }
131
132 ret = InstallModulePackage(path);
133 return ret;
134 }
135
GetHmpUpdateResult()136 std::vector<HmpUpdateInfo> ModuleUpdateService::GetHmpUpdateResult()
137 {
138 LOG(INFO) << "GetHmpUpdateResult";
139 std::vector<HmpUpdateInfo> updateInfo {};
140 std::ifstream ifs { MODULE_RESULT_PATH };
141 if (!ifs.is_open()) {
142 LOG(ERROR) << "open " << MODULE_RESULT_PATH << " failed";
143 return updateInfo;
144 }
145 std::string resultInfo {std::istreambuf_iterator<char> {ifs}, {}};
146 std::vector<std::string> results {};
147 SplitStr(resultInfo, "\n", results);
148 for (auto &result : results) {
149 HmpUpdateInfo tmpUpdateInfo {};
150 std::vector<std::string> signalResult {};
151 SplitStr(result, ";", signalResult);
152 if (signalResult.size() < 3) { // 3: pkg; result; result info
153 LOG(ERROR) << "parse " << result << " failed";
154 continue;
155 }
156 tmpUpdateInfo.path = signalResult[0];
157 tmpUpdateInfo.result = stoi(signalResult[1]);
158 tmpUpdateInfo.resultMsg = signalResult[2]; // 2: result info
159 bool isFind = false;
160 for (auto &iter : updateInfo) {
161 if (iter.path.find(tmpUpdateInfo.path) != std::string::npos) {
162 iter.result = tmpUpdateInfo.result;
163 iter.resultMsg = tmpUpdateInfo.resultMsg;
164 isFind = true;
165 break;
166 }
167 }
168 if (!isFind) {
169 updateInfo.emplace_back(tmpUpdateInfo);
170 }
171 }
172 ifs.close();
173 (void)unlink(MODULE_RESULT_PATH);
174 return updateInfo;
175 }
176
OnStart(const SystemAbilityOnDemandReason & startReason)177 void ModuleUpdateService::OnStart(const SystemAbilityOnDemandReason &startReason)
178 {
179 InitUpdaterLogger("ModuleUpdaterServer", "", "", "");
180 LOG(INFO) << "OnStart, startReason name: " << startReason.GetName() << ", id: " <<
181 static_cast<int32_t>(startReason.GetId()) << ", value: " << startReason.GetValue();
182 SysInstaller::ModuleUpdateMain& moduleUpdate = SysInstaller::ModuleUpdateMain::GetInstance();
183 moduleUpdate.ScanPreInstalledHmp();
184 bool res = Publish(this);
185 if (!res) {
186 LOG(ERROR) << "OnStart failed";
187 }
188 if ((strcmp(startReason.GetName().c_str(), SA_START) == 0 &&
189 strcmp(startReason.GetValue().c_str(), SA_ABNORMAL) == 0) ||
190 (strcmp(startReason.GetName().c_str(), BMS_START_INSTALL) == 0 &&
191 strcmp(startReason.GetValue().c_str(), BMS_REVERT) == 0)) {
192 moduleUpdate.Start();
193 }
194 LOG(INFO) << "OnStart done";
195 }
196
OnStop(const SystemAbilityOnDemandReason & stopReason)197 void ModuleUpdateService::OnStop(const SystemAbilityOnDemandReason &stopReason)
198 {
199 LOG(INFO) << "OnStop, stopReason name: " << stopReason.GetName() << ", id: " <<
200 static_cast<int32_t>(stopReason.GetId()) << ", value: " << stopReason.GetValue();
201 ModuleUpdateMain::GetInstance().ExitModuleUpdate();
202 }
203 } // namespace SysInstaller
204 } // namespace OHOS
205