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 &param)
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 &param, 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 }