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 #include "update_engine_controller.h"
16 #include <fstream>
17 #include "securec.h"
18 #include "intell_voice_log.h"
19
20 #include "update_adapter_listener.h"
21 #include "history_info_mgr.h"
22 #include "time_util.h"
23 #include "scope_guard.h"
24 #include "trigger_manager.h"
25 #include "adapter_callback_service.h"
26 #include "string_util.h"
27
28 #define LOG_TAG "UpdateEngineController"
29
30 using namespace OHOS::IntellVoiceUtils;
31
32 namespace OHOS {
33 namespace IntellVoiceEngine {
34 static constexpr int32_t MS_PER_S = 1000;
35
36 std::atomic<bool> UpdateEngineController::isUpdating_ = false;
37
UpdateEngineController()38 UpdateEngineController::UpdateEngineController()
39 {
40 }
41
~UpdateEngineController()42 UpdateEngineController::~UpdateEngineController()
43 {
44 }
45
OnTimerEvent(TimerEvent & info)46 void UpdateEngineController::OnTimerEvent(TimerEvent &info)
47 {
48 INTELL_VOICE_LOG_INFO("TimerEvent %{public}d", timerId_);
49 HandleUpdateRetry();
50 }
51
UpdateRetryProc()52 bool UpdateEngineController::UpdateRetryProc()
53 {
54 std::lock_guard<std::mutex> lock(updateEngineMutex_);
55 if (isForceReleased_) {
56 INTELL_VOICE_LOG_WARN("force to stop, no need to retry");
57 return true;
58 }
59 if (updateStrategy_ != nullptr && !updateStrategy_->UpdateRestrain()) {
60 if (CreateUpdateEngine(updateStrategy_->param_)) {
61 INTELL_VOICE_LOG_INFO("retry update, times %{public}d", retryTimes_);
62 timerId_ = INVALID_ID;
63 return true;
64 }
65 updateResult_ = UpdateState::UPDATE_STATE_COMPLETE_FAIL;
66 } else {
67 updateResult_ = UpdateState::UPDATE_STATE_COMPLETE_SUCCESS;
68 }
69
70 INTELL_VOICE_LOG_INFO("retry err, times %{public}d, result %{public}d", retryTimes_, updateResult_);
71 ClearRetryState();
72 ReleaseUpdateEngine();
73 TimerMgr::Stop();
74 return false;
75 }
76
UpdateArbitration(int priority)77 int UpdateEngineController::UpdateArbitration(int priority)
78 {
79 if (!GetUpdateState()) {
80 return 0;
81 }
82
83 if (curPriority_ > priority) {
84 INTELL_VOICE_LOG_INFO("cur priority is higher than new, can not create");
85 return -1;
86 }
87
88 if (curPriority_ == priority) {
89 INTELL_VOICE_LOG_INFO("same priority, retry update process");
90 return 0;
91 }
92
93 INTELL_VOICE_LOG_INFO("cur priority is lower than before, release old engine");
94 if (updateStrategy_ != nullptr) {
95 updateStrategy_->OnUpdateCompleteCallback(UPDATE_STATE_COMPLETE_FAIL, true);
96 }
97 ReleaseUpdateEngine();
98 ClearRetryState();
99 TimerMgr::Stop();
100 return 0;
101 }
102
CreateUpdateEngineUntilTime(std::shared_ptr<IUpdateStrategy> updateStrategy)103 int UpdateEngineController::CreateUpdateEngineUntilTime(std::shared_ptr<IUpdateStrategy> updateStrategy)
104 {
105 std::lock_guard<std::mutex> lock(updateEngineMutex_);
106 INTELL_VOICE_LOG_INFO("enter");
107 if (updateStrategy == nullptr) {
108 INTELL_VOICE_LOG_INFO("strategy is null");
109 return -1;
110 }
111
112 if (updateStrategy->UpdateRestrain()) {
113 INTELL_VOICE_LOG_INFO("update restrain, no need to update");
114 return -1;
115 }
116
117 if (UpdateArbitration(updateStrategy->GetUpdatePriority()) != 0) {
118 return -1;
119 }
120
121 if (!CreateUpdateEngine(updateStrategy->param_)) {
122 INTELL_VOICE_LOG_ERROR("create update engine error");
123 return -1;
124 }
125
126 retryTimesLimit_ = updateStrategy->GetRetryTimes();
127 if (retryTimes_ < retryTimesLimit_) {
128 TimerMgr::Start("UpdateThread", nullptr);
129 }
130
131 updateStrategy_ = updateStrategy;
132 curPriority_ = updateStrategy->GetUpdatePriority();
133 SetUpdateState(true);
134 isForceReleased_ = false;
135
136 INTELL_VOICE_LOG_INFO("create update engine success");
137 return 0;
138 }
139
StartUpdateTimer()140 bool UpdateEngineController::StartUpdateTimer()
141 {
142 if (timerId_ != INVALID_ID) {
143 INTELL_VOICE_LOG_INFO("timer already start %{public}d", timerId_);
144 return true;
145 }
146
147 timerId_ = SetTimer(0, delaySecond_ * MS_PER_S * US_PER_MS, 0, this);
148 if (timerId_ == INVALID_ID) {
149 INTELL_VOICE_LOG_ERROR("timerId %{public}d is invalid", timerId_);
150 return false;
151 }
152
153 retryTimes_++;
154 INTELL_VOICE_LOG_INFO("start update timer succeed");
155 return true;
156 }
157
StopUpdateTimer()158 void UpdateEngineController::StopUpdateTimer()
159 {
160 if (timerId_ == INVALID_ID) {
161 INTELL_VOICE_LOG_INFO("timer already stop");
162 return;
163 }
164
165 KillTimer(timerId_);
166 INTELL_VOICE_LOG_INFO("stop update timer");
167 }
168
IsNeedRetryUpdate()169 bool UpdateEngineController::IsNeedRetryUpdate()
170 {
171 if (updateResult_ == UpdateState::UPDATE_STATE_COMPLETE_SUCCESS) {
172 INTELL_VOICE_LOG_INFO("update success");
173 return false;
174 }
175
176 if (retryTimes_ >= retryTimesLimit_) {
177 INTELL_VOICE_LOG_INFO("retry times limit");
178 return false;
179 }
180
181 if ((updateStrategy_ == nullptr) || (updateStrategy_->UpdateRestrain())) {
182 INTELL_VOICE_LOG_INFO("no need to retry");
183 return false;
184 }
185
186 return true;
187 }
188
ClearRetryState()189 void UpdateEngineController::ClearRetryState()
190 {
191 retryTimes_ = 0;
192 updateResult_ = UpdateState::UPDATE_STATE_DEFAULT;
193 timerId_ = INVALID_ID;
194 updateStrategy_ = nullptr;
195 retryTimesLimit_ = 0;
196 curPriority_ = 0;
197 SetUpdateState(false);
198 }
199
OnUpdateComplete(UpdateState result,const std::string & param)200 void UpdateEngineController::OnUpdateComplete(UpdateState result, const std::string ¶m)
201 {
202 HandleUpdateComplete(result, param);
203 }
204
UpdateCompleteProc(UpdateState result,const std::string & param,bool & isLast)205 void UpdateEngineController::UpdateCompleteProc(UpdateState result, const std::string ¶m, bool &isLast)
206 {
207 std::lock_guard<std::mutex> lock(updateEngineMutex_);
208 isLast = false;
209 if (isForceReleased_) {
210 HistoryInfoMgr::GetInstance().DeleteKey({ KEY_WAKEUP_VESRION });
211 INTELL_VOICE_LOG_WARN("already stop");
212 return;
213 }
214 if (updateStrategy_ == nullptr || param != updateStrategy_->param_) {
215 INTELL_VOICE_LOG_WARN("param is not equal");
216 return;
217 }
218 updateResult_ = result;
219 StopUpdateTimer();
220
221 if (IsNeedRetryUpdate() && StartUpdateTimer()) {
222 INTELL_VOICE_LOG_INFO("retry to update");
223 } else {
224 if (updateStrategy_ != nullptr) {
225 updateStrategy_->OnUpdateCompleteCallback(result != UpdateState::UPDATE_STATE_COMPLETE_SUCCESS, true);
226 }
227 ClearRetryState();
228 isLast = true;
229 TimerMgr::Stop();
230 }
231 ReleaseUpdateEngine();
232 }
233
ForceRelease()234 void UpdateEngineController::ForceRelease()
235 {
236 std::lock_guard<std::mutex> lock(updateEngineMutex_);
237 if (!GetUpdateState()) {
238 INTELL_VOICE_LOG_INFO("no need to stop update");
239 return;
240 }
241 ClearRetryState();
242 ReleaseUpdateEngine();
243 TimerMgr::Stop();
244 isForceReleased_ = true;
245 }
246 }
247 }