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_CANCEL_AUTH, S_WIDGET_AUTH_FINISHED,
62 [this](FiniteStateMachine &machine, uint32_t event) { OnStopSchedule(machine, event); });
63 builder->MakeTransition(S_WIDGET_AUTH_RUNNING, E_NAVI_PIN_AUTH, S_WIDGET_AUTH_FINISHED,
64 [this](FiniteStateMachine &machine, uint32_t event) { OnNaviPinAuth(machine, event); });
65 builder->MakeTransition(S_WIDGET_AUTH_RUNNING, E_START_AUTH, S_WIDGET_AUTH_RUNNING,
66 [this](FiniteStateMachine &machine, uint32_t event) { OnStartAuth(machine, event); });
67 builder->MakeTransition(S_WIDGET_AUTH_RUNNING, E_UPDATE_AUTH, S_WIDGET_AUTH_RUNNING,
68 [this](FiniteStateMachine &machine, uint32_t event) { OnStopAuthList(machine, event); });
69 builder->MakeTransition(S_WIDGET_WAITING, E_WIDGET_PARA_INVALID, S_WIDGET_AUTH_FINISHED,
70 [this](FiniteStateMachine &machine, uint32_t event) { OnWidgetParaInvalid(machine, event); });
71 builder->MakeTransition(S_WIDGET_AUTH_RUNNING, E_WIDGET_PARA_INVALID, S_WIDGET_AUTH_FINISHED,
72 [this](FiniteStateMachine &machine, uint32_t event) { OnWidgetParaInvalid(machine, event); });
73 // Add for AuthWidget rotate
74 builder->MakeTransition(S_WIDGET_AUTH_RUNNING, E_WIDGET_RELOAD, S_WIDGET_RELOAD_WAITING,
75 [this](FiniteStateMachine &machine, uint32_t event) { OnWidgetReloadInit(machine, event); });
76 builder->MakeTransition(S_WIDGET_WAITING, E_WIDGET_RELOAD, S_WIDGET_RELOAD_WAITING,
77 [this](FiniteStateMachine &machine, uint32_t event) { OnWidgetReloadInit(machine, event); });
78 builder->MakeTransition(S_WIDGET_RELOAD_WAITING, E_CANCEL_AUTH, S_WIDGET_WAITING,
79 [this](FiniteStateMachine &machine, uint32_t event) { OnWidgetReload(machine, event); });
80
81 return builder->Build();
82 }
83
TryKickMachine(Event event)84 bool WidgetScheduleNodeImpl::TryKickMachine(Event event)
85 {
86 if (machine_ == nullptr) {
87 IAM_LOGE("Invalid FSM of widget schedule");
88 return false;
89 }
90 machine_->Schedule(event);
91 return true;
92 }
93
StartSchedule()94 bool WidgetScheduleNodeImpl::StartSchedule()
95 {
96 iamHitraceHelper_ = Common::MakeShared<IamHitraceHelper>("widget_schedule");
97 {
98 std::lock_guard<std::mutex> lock(mutex_);
99 if (!TryKickMachine(E_START_WIDGET)) {
100 return false;
101 }
102 }
103 return true;
104 }
105
StopSchedule()106 bool WidgetScheduleNodeImpl::StopSchedule()
107 {
108 std::lock_guard<std::mutex> lock(mutex_);
109 return TryKickMachine(E_CANCEL_AUTH);
110 }
111
StartAuthList(const std::vector<AuthType> & authTypeList,bool endAfterFirstFail,AuthIntent authIntent)112 bool WidgetScheduleNodeImpl::StartAuthList(const std::vector<AuthType> &authTypeList, bool endAfterFirstFail,
113 AuthIntent authIntent)
114 {
115 std::lock_guard<std::mutex> lock(mutex_);
116 startAuthTypeList_.clear();
117 for (auto authType : authTypeList) {
118 startAuthTypeList_.emplace_back(authType);
119 IAM_LOGI("Command(type:%{public}d) on result start.", authType);
120 }
121 endAfterFirstFail_ = endAfterFirstFail;
122 authIntent_ = authIntent;
123 return TryKickMachine(E_START_AUTH);
124 }
125
StopAuthList(const std::vector<AuthType> & authTypeList)126 bool WidgetScheduleNodeImpl::StopAuthList(const std::vector<AuthType> &authTypeList)
127 {
128 std::lock_guard<std::mutex> lock(mutex_);
129 stopAuthTypeList_ = authTypeList;
130 return TryKickMachine(E_UPDATE_AUTH);
131 }
132
SuccessAuth(AuthType authType)133 bool WidgetScheduleNodeImpl::SuccessAuth(AuthType authType)
134 {
135 std::lock_guard<std::mutex> lock(mutex_);
136 successAuthType_ = authType;
137 IAM_LOGI("success %{public}d.", E_COMPLETE_AUTH);
138 return TryKickMachine(E_COMPLETE_AUTH);
139 }
140
NaviPinAuth()141 bool WidgetScheduleNodeImpl::NaviPinAuth()
142 {
143 std::lock_guard<std::mutex> lock(mutex_);
144 return TryKickMachine(E_NAVI_PIN_AUTH);
145 }
146
WidgetParaInvalid()147 bool WidgetScheduleNodeImpl::WidgetParaInvalid()
148 {
149 std::lock_guard<std::mutex> lock(mutex_);
150 return TryKickMachine(E_WIDGET_PARA_INVALID);
151 }
152
WidgetReload(uint32_t orientation,uint32_t needRotate,uint32_t alreadyLoad,AuthType & rotateAuthType)153 bool WidgetScheduleNodeImpl::WidgetReload(uint32_t orientation, uint32_t needRotate, uint32_t alreadyLoad,
154 AuthType &rotateAuthType)
155 {
156 std::lock_guard<std::mutex> lock(mutex_);
157 orientation_ = orientation;
158 needRotate_ = needRotate;
159 alreadyLoad_ = alreadyLoad;
160 rotateAuthType_ = rotateAuthType;
161 return TryKickMachine(E_WIDGET_RELOAD);
162 }
163
SetCallback(std::shared_ptr<WidgetScheduleNodeCallback> callback)164 void WidgetScheduleNodeImpl::SetCallback(std::shared_ptr<WidgetScheduleNodeCallback> callback)
165 {
166 callback_ = callback;
167 }
168
OnStartSchedule(FiniteStateMachine & machine,uint32_t event)169 void WidgetScheduleNodeImpl::OnStartSchedule(FiniteStateMachine &machine, uint32_t event)
170 {
171 auto callback = callback_.lock();
172 IF_FALSE_LOGE_AND_RETURN(callback != nullptr);
173 if (!callback->LaunchWidget()) {
174 IAM_LOGE("Failed to launch widget, cancel Auth");
175 StopSchedule();
176 }
177 }
178
OnStopSchedule(FiniteStateMachine & machine,uint32_t event)179 void WidgetScheduleNodeImpl::OnStopSchedule(FiniteStateMachine &machine, uint32_t event)
180 {
181 auto callback = callback_.lock();
182 IF_FALSE_LOGE_AND_RETURN(callback != nullptr);
183 callback->EndAuthAsCancel();
184 iamHitraceHelper_ = nullptr;
185 }
186
OnStartAuth(FiniteStateMachine & machine,uint32_t event)187 void WidgetScheduleNodeImpl::OnStartAuth(FiniteStateMachine &machine, uint32_t event)
188 {
189 auto callback = callback_.lock();
190 IF_FALSE_LOGE_AND_RETURN(callback != nullptr);
191 std::set<AuthType> startAuthTypeSet;
192 for (auto authType : startAuthTypeList_) {
193 if (runningAuthTypeSet_.find(authType) == runningAuthTypeSet_.end()) {
194 startAuthTypeSet.emplace(authType);
195 }
196 }
197 callback->ExecuteAuthList(startAuthTypeSet, endAfterFirstFail_, authIntent_);
198 }
199
OnStopAuthList(FiniteStateMachine & machine,uint32_t event)200 void WidgetScheduleNodeImpl::OnStopAuthList(FiniteStateMachine &machine, uint32_t event)
201 {
202 auto callback = callback_.lock();
203 IF_FALSE_LOGE_AND_RETURN(callback != nullptr);
204 for (auto authType : stopAuthTypeList_) {
205 runningAuthTypeSet_.erase(authType);
206 }
207 callback->StopAuthList(stopAuthTypeList_);
208 }
209
OnSuccessAuth(FiniteStateMachine & machine,uint32_t event)210 void WidgetScheduleNodeImpl::OnSuccessAuth(FiniteStateMachine &machine, uint32_t event)
211 {
212 auto callback = callback_.lock();
213 IF_FALSE_LOGE_AND_RETURN(callback != nullptr);
214 runningAuthTypeSet_.erase(successAuthType_);
215 callback->SuccessAuth(successAuthType_);
216 }
217
OnNaviPinAuth(FiniteStateMachine & machine,uint32_t event)218 void WidgetScheduleNodeImpl::OnNaviPinAuth(FiniteStateMachine &machine, uint32_t event)
219 {
220 auto callback = callback_.lock();
221 IF_FALSE_LOGE_AND_RETURN(callback != nullptr);
222 callback->EndAuthAsNaviPin();
223 }
224
OnWidgetParaInvalid(FiniteStateMachine & machine,uint32_t event)225 void WidgetScheduleNodeImpl::OnWidgetParaInvalid(FiniteStateMachine &machine, uint32_t event)
226 {
227 auto callback = callback_.lock();
228 IF_FALSE_LOGE_AND_RETURN(callback != nullptr);
229 callback->EndAuthAsWidgetParaInvalid();
230 }
231
OnWidgetReloadInit(FiniteStateMachine & machine,uint32_t event)232 void WidgetScheduleNodeImpl::OnWidgetReloadInit(FiniteStateMachine &machine, uint32_t event)
233 {
234 auto callback = callback_.lock();
235 IF_FALSE_LOGE_AND_RETURN(callback != nullptr);
236 IAM_LOGI("Widget need reload, init");
237 callback->AuthWidgetReloadInit();
238 }
239
OnWidgetReload(FiniteStateMachine & machine,uint32_t event)240 void WidgetScheduleNodeImpl::OnWidgetReload(FiniteStateMachine &machine, uint32_t event)
241 {
242 auto callback = callback_.lock();
243 IF_FALSE_LOGE_AND_RETURN(callback != nullptr);
244 IAM_LOGI("Widget need reload");
245 const uint32_t reloadInitMs = 100;
246 auto sleepTime = std::chrono::milliseconds(reloadInitMs);
247 std::this_thread::sleep_for(sleepTime);
248 if (!callback->AuthWidgetReload(orientation_, needRotate_, alreadyLoad_, rotateAuthType_)) {
249 IAM_LOGE("Failed to reload widget, cancel Auth");
250 StopSchedule();
251 }
252 }
253 } // namespace UserAuth
254 } // namespace UserIam
255 } // namespace OHOS