1 /*
2 * Copyright (c) 2024 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_consumer.h"
17 #include <vector>
18 #include "directory_ex.h"
19 #include "log/log.h"
20 #include "module_constants.h"
21 #include "module_error_code.h"
22 #include "module_update.h"
23 #include "module_update_main.h"
24 #include "module_utils.h"
25 #include "parameter.h"
26 #include "scope_guard.h"
27
28 namespace OHOS {
29 namespace SysInstaller {
30 using namespace Updater;
31
ModuleUpdateConsumer(ModuleUpdateQueue & queue,std::unordered_map<int32_t,std::string> & saIdHmpMap,volatile sig_atomic_t & exit)32 ModuleUpdateConsumer::ModuleUpdateConsumer(ModuleUpdateQueue &queue,
33 std::unordered_map<int32_t, std::string> &saIdHmpMap, volatile sig_atomic_t &exit)
34 : queue_(queue),
35 saIdHmpMap_(saIdHmpMap),
36 exit_(exit) {}
37
DoInstall(ModuleUpdateStatus & status)38 void ModuleUpdateConsumer::DoInstall(ModuleUpdateStatus &status)
39 {
40 ON_SCOPE_EXIT(rmdir) {
41 RemoveSpecifiedDir(std::string(UPDATE_INSTALL_DIR) + "/" + status.hmpName);
42 };
43 if (ModuleUpdate::GetInstance().DoModuleUpdate(status)) {
44 LOG(INFO) << "hmp package successful install, hmp name=" << status.hmpName;
45 } else {
46 LOG(ERROR) << "hmp package fail install, hmp name=" << status.hmpName;
47 }
48 }
49
DoRevert(const std::string & hmpName,int32_t saId)50 void ModuleUpdateConsumer::DoRevert(const std::string &hmpName, int32_t saId)
51 {
52 LOG(INFO) << "hmp package revert,hmp name=" << hmpName << "; said=" << saId;
53 bool isHotHmp = IsHotHmpPackage(hmpName);
54 ModuleUpdateStatus status;
55 status.hmpName = hmpName;
56 status.isHotInstall = isHotHmp;
57 Revert(hmpName, !isHotHmp);
58 DoInstall(status);
59 }
60
DoUnload(const std::string & hmpName,int32_t saId)61 void ModuleUpdateConsumer::DoUnload(const std::string &hmpName, int32_t saId)
62 {
63 LOG(INFO) << "hmp package unload,hmp name=" << hmpName << "; said=" << saId;
64 ModuleUpdateStatus status;
65 status.hmpName = hmpName;
66 status.isHotInstall = true;
67 if (IsRunning(saId)) {
68 LOG(INFO) << "sa is running, saId=" << saId;
69 return;
70 }
71 // check whether install hmp exists
72 DoInstall(status);
73 }
74
Run()75 void ModuleUpdateConsumer::Run()
76 {
77 LOG(INFO) << "ModuleUpdateConsumer Consume";
78 do {
79 if (exit_ == 1 && queue_.IsEmpty()) {
80 queue_.Stop();
81 break;
82 }
83 std::pair<int32_t, std::string> saStatusPair = queue_.Pop();
84 if (saStatusPair.first == 0 && saStatusPair.second == "") {
85 LOG(INFO) << "producer and consumer stop";
86 break;
87 }
88 Timer timer;
89 if (saStatusPair.first == APP_SERIAL_NUMBER) {
90 ModuleUpdateMain::GetInstance().SaveInstallerResult(saStatusPair.second, ModuleErrorCode::ERR_BMS_REVERT,
91 saStatusPair.second + " revert", timer);
92 DoRevert(saStatusPair.second, APP_SERIAL_NUMBER);
93 continue;
94 }
95 int32_t saId = saStatusPair.first;
96 std::string saStatus = saStatusPair.second;
97 auto it = saIdHmpMap_.find(saId);
98 if (it == saIdHmpMap_.end() || it->second == "") {
99 LOG(ERROR) << "find hmp fail, saId=" << saId;
100 continue;
101 }
102 std::string hmpName = it->second;
103 if (strcmp(saStatus.c_str(), LOAD_FAIL) == 0 || strcmp(saStatus.c_str(), CRASH) == 0) {
104 ModuleUpdateMain::GetInstance().SaveInstallerResult(hmpName, ModuleErrorCode::ERR_SAMGR_REVERT,
105 std::to_string(saId) + " revert", timer);
106 DoRevert(hmpName, saId);
107 } else if (IsHotSa(saId) && strcmp(saStatus.c_str(), UNLOAD) == 0) {
108 DoUnload(hmpName, saId);
109 } else {
110 LOG(ERROR) << "sa status not exist, said=" << saId;
111 }
112 } while (true);
113 LOG(INFO) << "consumer exit";
114 }
115 } // SysInstaller
116 } // namespace OHOS