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