1 /*
2 * Copyright (c) 2022 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 "action_processer.h"
17 #include <chrono>
18 #include <thread>
19 #include "sys_installer_manager.h"
20 #include "log/log.h"
21
22 namespace OHOS {
23 namespace SysInstaller {
24 using namespace Updater;
IsRunning()25 bool ActionProcesser::IsRunning()
26 {
27 return isRunning_ || isSuspend_;
28 }
29
WaitActionExit()30 bool ActionProcesser::WaitActionExit()
31 {
32 using namespace std::chrono_literals;
33 const unsigned int WAIT_MAX_SECOND = 4;
34 unsigned int count = 0;
35 while (IsRunning() && (count < WAIT_MAX_SECOND)) {
36 std::this_thread::sleep_for(1s);
37 count++;
38 }
39 if (count == WAIT_MAX_SECOND) {
40 LOG(ERROR) << "wait action exit failed for " << WAIT_MAX_SECOND << "s";
41 return false;
42 }
43 LOG(INFO) << "action exit after " << count << "s";
44 return true;
45 }
46
AddAction(std::unique_ptr<IAction> action)47 void ActionProcesser::AddAction(std::unique_ptr<IAction> action)
48 {
49 if (isRunning_ || action == nullptr) {
50 LOG(ERROR) << "action running or action empty";
51 return;
52 }
53
54 LOG(INFO) << "add " << action->GetActionName();
55 auto callBack = [this](InstallerErrCode errCode, const std::string &errStr) {
56 CompletedAction(errCode, errStr);
57 };
58 action->SetCallback(callBack);
59 actionQue_.push_back(std::move(action));
60 }
61
Start()62 void ActionProcesser::Start()
63 {
64 if (isRunning_ || actionQue_.empty()) {
65 LOG(WARNING) << "Action running or queue empty";
66 return;
67 }
68
69 isRunning_ = true;
70 isSuspend_ = false;
71 statusManager_->UpdateCallback(UpdateStatus::UPDATE_STATE_ONGOING, 0, "");
72 curAction_ = std::move(actionQue_.front());
73 actionQue_.pop_front();
74 if (curAction_ == nullptr) {
75 LOG(WARNING) << "curAction_ nullptr";
76 return;
77 }
78 LOG(INFO) << "Start " << curAction_->GetActionName();
79 curAction_->PerformAction();
80 }
81
Stop()82 bool ActionProcesser::Stop()
83 {
84 if (!isRunning_) {
85 LOG(WARNING) << "Action not running";
86 return false;
87 }
88 bool ret = false;
89 if (curAction_ != nullptr) {
90 LOG(INFO) << "Stop " << curAction_->GetActionName();
91 ret = curAction_->TerminateAction();
92 }
93 if (!ret || !WaitActionExit()) {
94 LOG(INFO) << "Stop action failed, directly returned";
95 return false;
96 }
97 isRunning_ = false;
98 isSuspend_ = false;
99 curAction_.reset();
100 actionQue_.clear();
101 return ret;
102 }
103
Suspend()104 void ActionProcesser::Suspend()
105 {
106 if (!isRunning_ || curAction_ == nullptr) {
107 LOG(WARNING) << "ActionProcesser not running or action empty";
108 return;
109 }
110
111 LOG(INFO) << "Suspend " << curAction_->GetActionName();
112 isSuspend_ = true;
113 curAction_->SuspendAction();
114 }
115
Resume()116 void ActionProcesser::Resume()
117 {
118 if (isSuspend_) {
119 LOG(WARNING) << "ActionProcesser is running";
120 return;
121 }
122
123 isSuspend_ = false;
124 if (curAction_ != nullptr) {
125 LOG(INFO) << "Resume " << curAction_->GetActionName();
126 return curAction_->ResumeAction();
127 }
128
129 StartNextAction();
130 }
131
CompletedAction(InstallerErrCode errCode,const std::string & errStr)132 void ActionProcesser::CompletedAction(InstallerErrCode errCode, const std::string &errStr)
133 {
134 if (curAction_ == nullptr) {
135 LOG(ERROR) << "curAction_ null error ";
136 return;
137 }
138
139 LOG(INFO) << "Completed " << curAction_->GetActionName();
140 curAction_.reset();
141 if (errCode != SYS_UPDATE_SUCCESS) {
142 isRunning_ = false;
143 isSuspend_ = false;
144 statusManager_->UpdateCallback(UpdateStatus::UPDATE_STATE_FAILED, 100, errStr); // 100 : action failed
145 actionQue_.clear();
146 LOG(ERROR) << "CompletedAction errCode:" << errCode << " str:" << errStr;
147 SysInstallerManagerInit::GetInstance().InvokeEvent(SYS_POST_EVENT);
148 return;
149 }
150
151 if (isSuspend_) {
152 LOG(INFO) << "suspend";
153 return;
154 }
155
156 StartNextAction();
157 }
158
StartNextAction()159 void ActionProcesser::StartNextAction()
160 {
161 if (actionQue_.empty()) {
162 LOG(INFO) << "Action queue empty, successful";
163 isRunning_ = false;
164 isSuspend_ = false;
165 statusManager_->UpdateCallback(UpdateStatus::UPDATE_STATE_SUCCESSFUL, 100, ""); // 100 : action completed
166 return;
167 }
168
169 curAction_ = std::move(actionQue_.front());
170 LOG(INFO) << "StartNextAction " << curAction_->GetActionName();
171 actionQue_.pop_front();
172 curAction_->PerformAction();
173 }
174
SetCpuAffinity(unsigned int reservedCores)175 bool ActionProcesser::SetCpuAffinity(unsigned int reservedCores)
176 {
177 if (!isRunning_ || curAction_ == nullptr) {
178 LOG(WARNING) << "ActionProcesser not running or action empty";
179 return false;
180 }
181 LOG(INFO) << "SetCpuAffinity " << curAction_->GetActionName();
182 bool ret = curAction_->SetCpuAffinityAction(reservedCores);
183 if (!ret) {
184 LOG(WARNING) << "SetCpuAffinity action filed";
185 return false;
186 }
187 return ret;
188 }
189 } // namespace SysInstaller
190 } // namespace OHOS
191