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 
18 #include "installer_manager.h"
19 #include "log/log.h"
20 
21 namespace OHOS {
22 namespace SysInstaller {
23 using namespace Updater;
24 
GetInstance()25 ActionProcesser &ActionProcesser::GetInstance()
26 {
27     static ActionProcesser instance;
28     return instance;
29 }
30 
IsRunning()31 bool ActionProcesser::IsRunning()
32 {
33     return isRunning_ || isSuspend_;
34 }
35 
AddAction(std::unique_ptr<IAction> action)36 void ActionProcesser::AddAction(std::unique_ptr<IAction> action)
37 {
38     if (isRunning_ || action == nullptr) {
39         LOG(ERROR) << "action running or action empty";
40         return;
41     }
42 
43     LOG(INFO) << "add " << action->GetActionName();
44     auto callBack = [this](InstallerErrCode errCode, const std::string &errStr) {
45         CompletedAction(errCode, errStr);
46     };
47     action->SetCallback(callBack);
48     actionQue_.push_back(std::move(action));
49 }
50 
Start()51 void ActionProcesser::Start()
52 {
53     if (isRunning_ || actionQue_.empty()) {
54         LOG(WARNING) << "Action running or queue empty";
55         return;
56     }
57 
58     isRunning_ = true;
59     isSuspend_ = false;
60     statusManager_->UpdateCallback(UPDATE_STATE_ONGOING, 0, "");
61     curAction_ = std::move(actionQue_.front());
62     actionQue_.pop_front();
63     if (curAction_ == nullptr) {
64         LOG(WARNING) << "curAction_ nullptr";
65         return;
66     }
67     LOG(INFO) << "Start " << curAction_->GetActionName();
68     curAction_->PerformAction();
69 }
70 
Stop()71 void ActionProcesser::Stop()
72 {
73     if (!isRunning_) {
74         LOG(WARNING) << "Action not running";
75         return;
76     }
77 
78     if (curAction_ != nullptr) {
79         LOG(INFO) << "Stop " << curAction_->GetActionName();
80         curAction_->TerminateAction();
81     }
82 
83     isRunning_ = false;
84     isSuspend_ = false;
85     curAction_.reset();
86     actionQue_.clear();
87 }
88 
Suspend()89 void ActionProcesser::Suspend()
90 {
91     if (!isRunning_ || curAction_ == nullptr) {
92         LOG(WARNING) << "ActionProcesser not running or action empty";
93         return;
94     }
95 
96     LOG(INFO) << "Suspend " << curAction_->GetActionName();
97     isSuspend_ = true;
98     curAction_->SuspendAction();
99 }
100 
Resume()101 void ActionProcesser::Resume()
102 {
103     if (isSuspend_) {
104         LOG(WARNING) << "ActionProcesser is running";
105         return;
106     }
107 
108     isSuspend_ = false;
109     if (curAction_ != nullptr) {
110         LOG(INFO) << "Resume " << curAction_->GetActionName();
111         return curAction_->ResumeAction();
112     }
113 
114     StartNextAction();
115 }
116 
CompletedAction(InstallerErrCode errCode,const std::string & errStr)117 void ActionProcesser::CompletedAction(InstallerErrCode errCode, const std::string &errStr)
118 {
119     if (curAction_ == nullptr) {
120         LOG(ERROR) << "curAction_ null error ";
121         return;
122     }
123 
124     LOG(INFO) << "Completed " << curAction_->GetActionName();
125     curAction_.reset();
126     if (errCode != SYS_UPDATE_SUCCESS) {
127         isRunning_ = false;
128         isSuspend_ = false;
129         statusManager_->UpdateCallback(UPDATE_STATE_FAILED, 100, errStr); // 100 : action failed
130         actionQue_.clear();
131         LOG(ERROR) << "CompletedAction errCode:" << errCode << " str:" << errStr;
132         SysInstallerManagerInit::GetInstance().InvokeEvent(SYS_POST_EVENT);
133         return;
134     }
135 
136     if (isSuspend_) {
137         LOG(INFO) << "suspend";
138         return;
139     }
140 
141     StartNextAction();
142 }
143 
144 
StartNextAction()145 void ActionProcesser::StartNextAction()
146 {
147     if (actionQue_.empty()) {
148         LOG(INFO) << "Action queue empty, successful";
149         isRunning_ = false;
150         isSuspend_ = false;
151         statusManager_->UpdateCallback(UPDATE_STATE_SUCCESSFUL, 100, ""); // 100 : action completed
152         return;
153     }
154 
155     curAction_ = std::move(actionQue_.front());
156     LOG(INFO) << "StartNextAction " << curAction_->GetActionName();
157     actionQue_.pop_front();
158     curAction_->PerformAction();
159 }
160 } // namespace SysInstaller
161 } // namespace OHOS
162