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_LABEL UserIam::Common::LABEL_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
74 return builder->Build();
75 }
76
TryKickMachine(Event event)77 bool WidgetScheduleNodeImpl::TryKickMachine(Event event)
78 {
79 if (machine_ == nullptr) {
80 IAM_LOGE("Invalid FSM of widget schedule");
81 return false;
82 }
83 machine_->Schedule(event);
84 return true;
85 }
86
StartSchedule()87 bool WidgetScheduleNodeImpl::StartSchedule()
88 {
89 iamHitraceHelper_ = Common::MakeShared<IamHitraceHelper>("widget_schedule");
90 {
91 std::lock_guard<std::mutex> lock(mutex_);
92 if (!TryKickMachine(E_START_WIDGET)) {
93 return false;
94 }
95 }
96 return true;
97 }
98
StopSchedule()99 bool WidgetScheduleNodeImpl::StopSchedule()
100 {
101 std::lock_guard<std::mutex> lock(mutex_);
102 return TryKickMachine(E_CANCEL_AUTH);
103 }
104
StartAuthList(const std::vector<AuthType> & authTypeList)105 bool WidgetScheduleNodeImpl::StartAuthList(const std::vector<AuthType> &authTypeList)
106 {
107 std::lock_guard<std::mutex> lock(mutex_);
108 startAuthTypeList_.clear();
109 for (auto authType : authTypeList) {
110 startAuthTypeList_.emplace_back(authType);
111 IAM_LOGI("Command(type:%{public}d) on result start.", authType);
112 }
113 return TryKickMachine(E_START_AUTH);
114 }
115
StopAuthList(const std::vector<AuthType> & authTypeList)116 bool WidgetScheduleNodeImpl::StopAuthList(const std::vector<AuthType> &authTypeList)
117 {
118 std::lock_guard<std::mutex> lock(mutex_);
119 stopAuthTypeList_ = authTypeList;
120 return TryKickMachine(E_UPDATE_AUTH);
121 }
122
SuccessAuth(AuthType authType)123 bool WidgetScheduleNodeImpl::SuccessAuth(AuthType authType)
124 {
125 std::lock_guard<std::mutex> lock(mutex_);
126 successAuthType_ = authType;
127 IAM_LOGI("success %{public}d.", E_COMPLETE_AUTH);
128 return TryKickMachine(E_COMPLETE_AUTH);
129 }
130
NaviPinAuth()131 bool WidgetScheduleNodeImpl::NaviPinAuth()
132 {
133 std::lock_guard<std::mutex> lock(mutex_);
134 return TryKickMachine(E_NAVI_PIN_AUTH);
135 }
136
WidgetParaInvalid()137 bool WidgetScheduleNodeImpl::WidgetParaInvalid()
138 {
139 std::lock_guard<std::mutex> lock(mutex_);
140 return TryKickMachine(E_WIDGET_PARA_INVALID);
141 }
142
SetCallback(std::shared_ptr<WidgetScheduleNodeCallback> callback)143 void WidgetScheduleNodeImpl::SetCallback(std::shared_ptr<WidgetScheduleNodeCallback> callback)
144 {
145 callback_ = callback;
146 }
147
OnStartSchedule(FiniteStateMachine & machine,uint32_t event)148 void WidgetScheduleNodeImpl::OnStartSchedule(FiniteStateMachine &machine, uint32_t event)
149 {
150 auto callback = callback_.lock();
151 IF_FALSE_LOGE_AND_RETURN(callback != nullptr);
152 if (!callback->LaunchWidget()) {
153 IAM_LOGE("Failed to launch widget, cancel Auth");
154 StopSchedule();
155 }
156 }
157
OnStopSchedule(FiniteStateMachine & machine,uint32_t event)158 void WidgetScheduleNodeImpl::OnStopSchedule(FiniteStateMachine &machine, uint32_t event)
159 {
160 auto callback = callback_.lock();
161 IF_FALSE_LOGE_AND_RETURN(callback != nullptr);
162 callback->EndAuthAsCancel();
163 iamHitraceHelper_ = nullptr;
164 }
165
OnStartAuth(FiniteStateMachine & machine,uint32_t event)166 void WidgetScheduleNodeImpl::OnStartAuth(FiniteStateMachine &machine, uint32_t event)
167 {
168 auto callback = callback_.lock();
169 IF_FALSE_LOGE_AND_RETURN(callback != nullptr);
170 std::set<AuthType> startAuthTypeSet;
171 for (auto authType : startAuthTypeList_) {
172 if (runningAuthTypeSet_.find(authType) == runningAuthTypeSet_.end()) {
173 startAuthTypeSet.emplace(authType);
174 }
175 }
176 callback->ExecuteAuthList(startAuthTypeSet);
177 }
178
OnStopAuthList(FiniteStateMachine & machine,uint32_t event)179 void WidgetScheduleNodeImpl::OnStopAuthList(FiniteStateMachine &machine, uint32_t event)
180 {
181 auto callback = callback_.lock();
182 IF_FALSE_LOGE_AND_RETURN(callback != nullptr);
183 for (auto authType : stopAuthTypeList_) {
184 runningAuthTypeSet_.erase(authType);
185 }
186 callback->StopAuthList(stopAuthTypeList_);
187 }
188
OnSuccessAuth(FiniteStateMachine & machine,uint32_t event)189 void WidgetScheduleNodeImpl::OnSuccessAuth(FiniteStateMachine &machine, uint32_t event)
190 {
191 auto callback = callback_.lock();
192 IF_FALSE_LOGE_AND_RETURN(callback != nullptr);
193 runningAuthTypeSet_.erase(successAuthType_);
194 callback->SuccessAuth(successAuthType_);
195 }
196
OnNaviPinAuth(FiniteStateMachine & machine,uint32_t event)197 void WidgetScheduleNodeImpl::OnNaviPinAuth(FiniteStateMachine &machine, uint32_t event)
198 {
199 auto callback = callback_.lock();
200 IF_FALSE_LOGE_AND_RETURN(callback != nullptr);
201 callback->EndAuthAsNaviPin();
202 }
203
OnWidgetParaInvalid(FiniteStateMachine & machine,uint32_t event)204 void WidgetScheduleNodeImpl::OnWidgetParaInvalid(FiniteStateMachine &machine, uint32_t event)
205 {
206 auto callback = callback_.lock();
207 IF_FALSE_LOGE_AND_RETURN(callback != nullptr);
208 callback->EndAuthAsWidgetParaInvalid();
209 }
210 } // namespace UserAuth
211 } // namespace UserIam
212 } // namespace OHOS