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 "widget_schedule_node_impl.h"
16
17 #include <mutex>
18 #include <sstream>
19
20 #include "nocopyable.h"
21
22 #include "iam_check.h"
23 #include "iam_logger.h"
24 #include "iam_ptr.h"
25 #include "iam_para2str.h"
26 #include "iam_common_defines.h"
27 #include "relative_timer.h"
28 #include "user_auth_common_defines.h"
29
30 #define LOG_TAG "USER_AUTH_SA"
31 namespace OHOS {
32 namespace UserIam {
33 namespace UserAuth {
WidgetScheduleNodeImpl()34 WidgetScheduleNodeImpl::WidgetScheduleNodeImpl()
35 {
36 machine_ = MakeFiniteStateMachine();
37 if (machine_ == nullptr) {
38 IAM_LOGE("Failed to create make FSM of widget schedule");
39 return;
40 }
41 threadHandler_ = ThreadHandler::GetSingleThreadInstance();
42 machine_->SetThreadHandler(threadHandler_);
43 }
44
MakeFiniteStateMachine()45 std::shared_ptr<FiniteStateMachine> WidgetScheduleNodeImpl::MakeFiniteStateMachine()
46 {
47 auto builder = FiniteStateMachine::Builder::New("widget_schedule", S_WIDGET_INIT);
48 if (builder == nullptr) {
49 return nullptr;
50 }
51 builder->MakeTransition(S_WIDGET_INIT, E_START_WIDGET, S_WIDGET_WAITING,
52 [this](FiniteStateMachine &machine, uint32_t event) { OnStartSchedule(machine, event); });
53 builder->MakeTransition(S_WIDGET_WAITING, E_START_AUTH, S_WIDGET_AUTH_RUNNING,
54 [this](FiniteStateMachine &machine, uint32_t event) { OnStartAuth(machine, event); });
55 builder->MakeTransition(S_WIDGET_WAITING, E_CANCEL_AUTH, S_WIDGET_AUTH_FINISHED,
56 [this](FiniteStateMachine &machine, uint32_t event) { OnStopSchedule(machine, event); });
57 builder->MakeTransition(S_WIDGET_WAITING, E_NAVI_PIN_AUTH, S_WIDGET_AUTH_FINISHED,
58 [this](FiniteStateMachine &machine, uint32_t event) { OnNaviPinAuth(machine, event); });
59 builder->MakeTransition(S_WIDGET_AUTH_RUNNING, E_COMPLETE_AUTH, S_WIDGET_AUTH_FINISHED,
60 [this](FiniteStateMachine &machine, uint32_t event) { OnSuccessAuth(machine, event); });
61 builder->MakeTransition(S_WIDGET_AUTH_RUNNING, E_STOP_AUTH, S_WIDGET_AUTH_FINISHED,
62 [this](FiniteStateMachine &machine, uint32_t event) { OnFailAuth(machine, event); });
63 builder->MakeTransition(S_WIDGET_AUTH_RUNNING, E_CANCEL_AUTH, S_WIDGET_AUTH_FINISHED,
64 [this](FiniteStateMachine &machine, uint32_t event) { OnStopSchedule(machine, event); });
65 builder->MakeTransition(S_WIDGET_AUTH_RUNNING, E_NAVI_PIN_AUTH, S_WIDGET_AUTH_FINISHED,
66 [this](FiniteStateMachine &machine, uint32_t event) { OnNaviPinAuth(machine, event); });
67 builder->MakeTransition(S_WIDGET_AUTH_RUNNING, E_START_AUTH, S_WIDGET_AUTH_RUNNING,
68 [this](FiniteStateMachine &machine, uint32_t event) { OnStartAuth(machine, event); });
69 builder->MakeTransition(S_WIDGET_AUTH_RUNNING, E_UPDATE_AUTH, S_WIDGET_AUTH_RUNNING,
70 [this](FiniteStateMachine &machine, uint32_t event) { OnStopAuthList(machine, event); });
71 builder->MakeTransition(S_WIDGET_WAITING, E_WIDGET_PARA_INVALID, S_WIDGET_AUTH_FINISHED,
72 [this](FiniteStateMachine &machine, uint32_t event) { OnWidgetParaInvalid(machine, event); });
73 builder->MakeTransition(S_WIDGET_AUTH_RUNNING, E_WIDGET_PARA_INVALID, S_WIDGET_AUTH_FINISHED,
74 [this](FiniteStateMachine &machine, uint32_t event) { OnWidgetParaInvalid(machine, event); });
75 // Add for AuthWidget rotate
76 builder->MakeTransition(S_WIDGET_AUTH_RUNNING, E_WIDGET_RELOAD, S_WIDGET_RELOAD_WAITING,
77 [this](FiniteStateMachine &machine, uint32_t event) { OnWidgetReloadInit(machine, event); });
78 builder->MakeTransition(S_WIDGET_WAITING, E_WIDGET_RELOAD, S_WIDGET_RELOAD_WAITING,
79 [this](FiniteStateMachine &machine, uint32_t event) { OnWidgetReloadInit(machine, event); });
80 builder->MakeTransition(S_WIDGET_RELOAD_WAITING, E_CANCEL_AUTH, S_WIDGET_WAITING,
81 [this](FiniteStateMachine &machine, uint32_t event) { OnWidgetReload(machine, event); });
82
83 builder->MakeTransition(S_WIDGET_INIT, E_WIDGET_RELEASE, S_WIDGET_RELEASED,
84 [this](FiniteStateMachine &machine, uint32_t event) { OnWidgetRelease(machine, event); });
85 builder->MakeTransition(S_WIDGET_WAITING, E_WIDGET_RELEASE, S_WIDGET_RELEASED,
86 [this](FiniteStateMachine &machine, uint32_t event) { OnWidgetRelease(machine, event); });
87 builder->MakeTransition(S_WIDGET_AUTH_RUNNING, E_WIDGET_RELEASE, S_WIDGET_RELEASED,
88 [this](FiniteStateMachine &machine, uint32_t event) { OnWidgetRelease(machine, event); });
89 builder->MakeTransition(S_WIDGET_AUTH_FINISHED, E_WIDGET_RELEASE, S_WIDGET_RELEASED,
90 [this](FiniteStateMachine &machine, uint32_t event) { OnWidgetRelease(machine, event); });
91 builder->MakeTransition(S_WIDGET_RELOAD_WAITING, E_WIDGET_RELEASE, S_WIDGET_RELEASED,
92 [this](FiniteStateMachine &machine, uint32_t event) { OnWidgetRelease(machine, event); });
93
94 return builder->Build();
95 }
96
TryKickMachine(Event event)97 bool WidgetScheduleNodeImpl::TryKickMachine(Event event)
98 {
99 if (machine_ == nullptr) {
100 IAM_LOGE("Invalid FSM of widget schedule");
101 return false;
102 }
103 machine_->Schedule(event);
104 return true;
105 }
106
StartSchedule()107 bool WidgetScheduleNodeImpl::StartSchedule()
108 {
109 iamHitraceHelper_ = Common::MakeShared<IamHitraceHelper>("widget_schedule");
110 {
111 std::lock_guard<std::mutex> lock(mutex_);
112 if (!TryKickMachine(E_START_WIDGET)) {
113 return false;
114 }
115 }
116 return true;
117 }
118
StopSchedule()119 bool WidgetScheduleNodeImpl::StopSchedule()
120 {
121 std::lock_guard<std::mutex> lock(mutex_);
122 return TryKickMachine(E_CANCEL_AUTH);
123 }
124
ClearSchedule()125 bool WidgetScheduleNodeImpl::ClearSchedule()
126 {
127 std::lock_guard<std::mutex> lock(mutex_);
128 return TryKickMachine(E_WIDGET_RELEASE);
129 }
130
StartAuthList(const std::vector<AuthType> & authTypeList,bool endAfterFirstFail,AuthIntent authIntent)131 bool WidgetScheduleNodeImpl::StartAuthList(const std::vector<AuthType> &authTypeList, bool endAfterFirstFail,
132 AuthIntent authIntent)
133 {
134 std::lock_guard<std::mutex> lock(mutex_);
135 startAuthTypeList_.clear();
136 for (auto authType : authTypeList) {
137 startAuthTypeList_.emplace_back(authType);
138 IAM_LOGI("Command(type:%{public}d) on result start.", authType);
139 }
140 endAfterFirstFail_ = endAfterFirstFail;
141 authIntent_ = authIntent;
142 return TryKickMachine(E_START_AUTH);
143 }
144
StopAuthList(const std::vector<AuthType> & authTypeList)145 bool WidgetScheduleNodeImpl::StopAuthList(const std::vector<AuthType> &authTypeList)
146 {
147 std::lock_guard<std::mutex> lock(mutex_);
148 stopAuthTypeList_ = authTypeList;
149 return TryKickMachine(E_UPDATE_AUTH);
150 }
151
SuccessAuth(AuthType authType)152 bool WidgetScheduleNodeImpl::SuccessAuth(AuthType authType)
153 {
154 std::lock_guard<std::mutex> lock(mutex_);
155 successAuthType_ = authType;
156 IAM_LOGI("success %{public}d.", E_COMPLETE_AUTH);
157 return TryKickMachine(E_COMPLETE_AUTH);
158 }
159
FailAuth(AuthType authType)160 bool WidgetScheduleNodeImpl::FailAuth(AuthType authType)
161 {
162 std::lock_guard<std::mutex> lock(mutex_);
163 failAuthType_ = authType;
164 IAM_LOGI("fail %{public}d.", E_STOP_AUTH);
165 return TryKickMachine(E_STOP_AUTH);
166 }
167
NaviPinAuth()168 bool WidgetScheduleNodeImpl::NaviPinAuth()
169 {
170 std::lock_guard<std::mutex> lock(mutex_);
171 return TryKickMachine(E_NAVI_PIN_AUTH);
172 }
173
WidgetParaInvalid()174 bool WidgetScheduleNodeImpl::WidgetParaInvalid()
175 {
176 std::lock_guard<std::mutex> lock(mutex_);
177 return TryKickMachine(E_WIDGET_PARA_INVALID);
178 }
179
WidgetReload(uint32_t orientation,uint32_t needRotate,uint32_t alreadyLoad,AuthType & rotateAuthType)180 bool WidgetScheduleNodeImpl::WidgetReload(uint32_t orientation, uint32_t needRotate, uint32_t alreadyLoad,
181 AuthType &rotateAuthType)
182 {
183 std::lock_guard<std::mutex> lock(mutex_);
184 orientation_ = orientation;
185 needRotate_ = needRotate;
186 alreadyLoad_ = alreadyLoad;
187 rotateAuthType_ = rotateAuthType;
188 return TryKickMachine(E_WIDGET_RELOAD);
189 }
190
SetCallback(std::shared_ptr<WidgetScheduleNodeCallback> callback)191 void WidgetScheduleNodeImpl::SetCallback(std::shared_ptr<WidgetScheduleNodeCallback> callback)
192 {
193 std::lock_guard<std::mutex> lock(mutex_);
194 callback_ = callback;
195 }
196
OnStartSchedule(FiniteStateMachine & machine,uint32_t event)197 void WidgetScheduleNodeImpl::OnStartSchedule(FiniteStateMachine &machine, uint32_t event)
198 {
199 auto callback = callback_.lock();
200 IF_FALSE_LOGE_AND_RETURN(callback != nullptr);
201 if (!callback->LaunchWidget()) {
202 IAM_LOGE("Failed to launch widget, cancel Auth");
203 StopSchedule();
204 }
205 }
206
OnStopSchedule(FiniteStateMachine & machine,uint32_t event)207 void WidgetScheduleNodeImpl::OnStopSchedule(FiniteStateMachine &machine, uint32_t event)
208 {
209 auto callback = callback_.lock();
210 IF_FALSE_LOGE_AND_RETURN(callback != nullptr);
211 callback->EndAuthAsCancel();
212 iamHitraceHelper_ = nullptr;
213 }
214
OnStartAuth(FiniteStateMachine & machine,uint32_t event)215 void WidgetScheduleNodeImpl::OnStartAuth(FiniteStateMachine &machine, uint32_t event)
216 {
217 auto callback = callback_.lock();
218 IF_FALSE_LOGE_AND_RETURN(callback != nullptr);
219 std::set<AuthType> startAuthTypeSet;
220 for (auto authType : startAuthTypeList_) {
221 if (runningAuthTypeSet_.find(authType) == runningAuthTypeSet_.end()) {
222 startAuthTypeSet.emplace(authType);
223 }
224 }
225 callback->ExecuteAuthList(startAuthTypeSet, endAfterFirstFail_, authIntent_);
226 }
227
OnStopAuthList(FiniteStateMachine & machine,uint32_t event)228 void WidgetScheduleNodeImpl::OnStopAuthList(FiniteStateMachine &machine, uint32_t event)
229 {
230 auto callback = callback_.lock();
231 IF_FALSE_LOGE_AND_RETURN(callback != nullptr);
232 for (auto authType : stopAuthTypeList_) {
233 runningAuthTypeSet_.erase(authType);
234 }
235 callback->StopAuthList(stopAuthTypeList_);
236 }
237
OnSuccessAuth(FiniteStateMachine & machine,uint32_t event)238 void WidgetScheduleNodeImpl::OnSuccessAuth(FiniteStateMachine &machine, uint32_t event)
239 {
240 auto callback = callback_.lock();
241 IF_FALSE_LOGE_AND_RETURN(callback != nullptr);
242 runningAuthTypeSet_.erase(successAuthType_);
243 callback->SuccessAuth(successAuthType_);
244 }
245
OnFailAuth(FiniteStateMachine & machine,uint32_t event)246 void WidgetScheduleNodeImpl::OnFailAuth(FiniteStateMachine &machine, uint32_t event)
247 {
248 auto callback = callback_.lock();
249 IF_FALSE_LOGE_AND_RETURN(callback != nullptr);
250 runningAuthTypeSet_.erase(successAuthType_);
251 callback->FailAuth(failAuthType_);
252 }
253
OnNaviPinAuth(FiniteStateMachine & machine,uint32_t event)254 void WidgetScheduleNodeImpl::OnNaviPinAuth(FiniteStateMachine &machine, uint32_t event)
255 {
256 auto callback = callback_.lock();
257 IF_FALSE_LOGE_AND_RETURN(callback != nullptr);
258 callback->EndAuthAsNaviPin();
259 }
260
OnWidgetParaInvalid(FiniteStateMachine & machine,uint32_t event)261 void WidgetScheduleNodeImpl::OnWidgetParaInvalid(FiniteStateMachine &machine, uint32_t event)
262 {
263 auto callback = callback_.lock();
264 IF_FALSE_LOGE_AND_RETURN(callback != nullptr);
265 callback->EndAuthAsWidgetParaInvalid();
266 }
267
OnWidgetReloadInit(FiniteStateMachine & machine,uint32_t event)268 void WidgetScheduleNodeImpl::OnWidgetReloadInit(FiniteStateMachine &machine, uint32_t event)
269 {
270 auto callback = callback_.lock();
271 IF_FALSE_LOGE_AND_RETURN(callback != nullptr);
272 IAM_LOGI("Widget need reload, init");
273 callback->AuthWidgetReloadInit();
274 }
275
OnWidgetReload(FiniteStateMachine & machine,uint32_t event)276 void WidgetScheduleNodeImpl::OnWidgetReload(FiniteStateMachine &machine, uint32_t event)
277 {
278 auto callback = callback_.lock();
279 IF_FALSE_LOGE_AND_RETURN(callback != nullptr);
280 IAM_LOGI("Widget need reload");
281 const uint32_t reloadInitMs = 100;
282 auto sleepTime = std::chrono::milliseconds(reloadInitMs);
283 std::this_thread::sleep_for(sleepTime);
284 if (!callback->AuthWidgetReload(orientation_, needRotate_, alreadyLoad_, rotateAuthType_)) {
285 IAM_LOGE("Failed to reload widget, cancel Auth");
286 StopSchedule();
287 }
288 }
289
OnWidgetRelease(FiniteStateMachine & machine,uint32_t event)290 void WidgetScheduleNodeImpl::OnWidgetRelease(FiniteStateMachine &machine, uint32_t event)
291 {
292 auto callback = callback_.lock();
293 IF_FALSE_LOGE_AND_RETURN(callback != nullptr);
294 IAM_LOGI("clear schedule");
295 callback->ClearSchedule();
296 }
297
SendAuthTipInfo(const std::vector<AuthType> & authTypeList,int32_t tipCode)298 void WidgetScheduleNodeImpl::SendAuthTipInfo(const std::vector<AuthType> &authTypeList, int32_t tipCode)
299 {
300 auto callback = callback_.lock();
301 IF_FALSE_LOGE_AND_RETURN(callback != nullptr);
302 IAM_LOGI("send mid auth result");
303 for (auto &authType : authTypeList) {
304 callback->SendAuthTipInfo(authType, tipCode);
305 }
306 }
307 } // namespace UserAuth
308 } // namespace UserIam
309 } // namespace OHOS
310