1 /*
2 * Copyright (c) 2021-2022 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
16 #include "account_state_machine.h"
17 #include "account_info.h"
18 #include "account_log_wrapper.h"
19 #include "datetime_ex.h"
20 #include "perf_stat.h"
21
22 namespace OHOS {
23 namespace AccountSA {
24 /**
25 * Account state machine initialize.
26 */
OnInitialize()27 void AccountStateMachine::OnInitialize()
28 {
29 stateMachineMap_ = {
30 // ACCOUNT_STATE_UNBOUND state
31 std::make_pair(ACCOUNT_STATE_UNBOUND, std::map<int, AccountStateAction *> {
32 // normal event, transform to login state
33 std::make_pair(ACCOUNT_BIND_SUCCESS_EVT, new (std::nothrow) LoginAction(ACCOUNT_STATE_LOGIN)),
34 // normal event, keep in unbound state
35 std::make_pair(ACCOUNT_BIND_FAILED_EVT, new (std::nothrow) ExceptionAction(ACCOUNT_STATE_UNBOUND)),
36 // unexpected event, re-initial state machine, check the state from account server
37 std::make_pair(ACCOUNT_AUTHENTICATE_SUCCESS_EVT, new (std::nothrow) LoginAction(ACCOUNT_STATE_LOGIN)),
38 // unexpected event, re-initial state machine, check the state from account server
39 std::make_pair(ACCOUNT_AUTHENTICATE_FAILED_EVT, nullptr),
40 // unexpected event, re-initial state machine, check the state from account server
41 std::make_pair(ACCOUNT_TOKEN_EXPIRED_EVT, nullptr),
42 // unexpected event, re-initial state machine, check the state from account server
43 std::make_pair(ACCOUNT_PASSWORD_CHANGED_EVT, nullptr),
44 // unexpected event, re-initial state machine, check the state from account server
45 std::make_pair(ACCOUNT_MANUAL_LOGOUT_EVT, nullptr),
46 // unexpected event, keep in unbound state
47 std::make_pair(ACCOUNT_MANUAL_UNBOUND_EVT, nullptr),
48 // unexpected event, keep in unbound state
49 std::make_pair(ACCOUNT_MANUAL_LOGOFF_EVT, nullptr)}
50 ),
51 // ACCOUNT_STATE_LOGIN state
52 std::make_pair(ACCOUNT_STATE_LOGIN, std::map<int, AccountStateAction *> {
53 // expected event, keep in login state
54 std::make_pair(ACCOUNT_BIND_SUCCESS_EVT, nullptr),
55 // unexpected event, re-initial state machine, check the state from account server
56 std::make_pair(ACCOUNT_BIND_FAILED_EVT, new (std::nothrow) ExceptionAction(ACCOUNT_STATE_LOGIN)),
57 // normal event, keep in login state
58 std::make_pair(ACCOUNT_AUTHENTICATE_SUCCESS_EVT, nullptr),
59 // normal event, transform to logout state
60 std::make_pair(ACCOUNT_AUTHENTICATE_FAILED_EVT, nullptr),
61 // expected event, transform to logout state
62 std::make_pair(ACCOUNT_TOKEN_EXPIRED_EVT, new (std::nothrow) LogoutAction(ACCOUNT_STATE_NOTLOGIN)),
63 // expected event, transform to logout state
64 std::make_pair(ACCOUNT_PASSWORD_CHANGED_EVT, new (std::nothrow) LogoutAction(ACCOUNT_STATE_NOTLOGIN)),
65 // expected event, transform to logout state
66 std::make_pair(ACCOUNT_MANUAL_LOGOUT_EVT, new (std::nothrow) LogoutAction(ACCOUNT_STATE_NOTLOGIN)),
67 // expected event, transform to unbound state
68 std::make_pair(ACCOUNT_MANUAL_UNBOUND_EVT, new (std::nothrow) UnboundAction(ACCOUNT_STATE_UNBOUND)),
69 // expected event, transform to logoff state
70 std::make_pair(ACCOUNT_MANUAL_LOGOFF_EVT, new (std::nothrow) LogoffAction(ACCOUNT_STATE_LOGOFF))}
71 ),
72 // ACCOUNT_STATE_NOTLOGIN state
73 std::make_pair(ACCOUNT_STATE_NOTLOGIN, std::map<int, AccountStateAction *> {
74 // normal event, transform to login state
75 std::make_pair(ACCOUNT_BIND_SUCCESS_EVT, new (std::nothrow) LoginAction(ACCOUNT_STATE_LOGIN)),
76 // unexpected event, re-initial state machine, check the state from account server
77 std::make_pair(ACCOUNT_BIND_FAILED_EVT, new (std::nothrow) ExceptionAction(ACCOUNT_STATE_NOTLOGIN)),
78 // expected event, transform to login state
79 std::make_pair(ACCOUNT_AUTHENTICATE_SUCCESS_EVT, new (std::nothrow) LoginAction(ACCOUNT_STATE_LOGIN)),
80 // expected event, keep in logout state
81 std::make_pair(ACCOUNT_AUTHENTICATE_FAILED_EVT, nullptr),
82 // unexpected event, re-initial state machine, check the state from account server
83 std::make_pair(ACCOUNT_TOKEN_EXPIRED_EVT, nullptr),
84 // unexpected event, re-initial state machine, check the state from account server
85 std::make_pair(ACCOUNT_PASSWORD_CHANGED_EVT, nullptr),
86 // unexpected event, re-initial state machine, check the state from account server
87 std::make_pair(ACCOUNT_MANUAL_LOGOUT_EVT, nullptr),
88 // expected event, transform to unbound state
89 std::make_pair(ACCOUNT_MANUAL_UNBOUND_EVT, new (std::nothrow) UnboundAction(ACCOUNT_STATE_UNBOUND)),
90 // expected event, transform to logoff state
91 std::make_pair(ACCOUNT_MANUAL_LOGOFF_EVT, new (std::nothrow) LogoffAction(ACCOUNT_STATE_LOGOFF))}
92 ),
93 // ACCOUNT_STATE_LOGOFF state
94 std::make_pair(ACCOUNT_STATE_LOGOFF, std::map<int, AccountStateAction *> {
95 // normal event, transform to login state
96 std::make_pair(ACCOUNT_BIND_SUCCESS_EVT, new (std::nothrow) LoginAction(ACCOUNT_STATE_LOGIN)),
97 // unexpected event, re-initial state machine, check the state from account server
98 std::make_pair(ACCOUNT_BIND_FAILED_EVT, new (std::nothrow) ExceptionAction(ACCOUNT_STATE_LOGOFF)),
99 // expected event, transform to login state
100 std::make_pair(ACCOUNT_AUTHENTICATE_SUCCESS_EVT, nullptr),
101 // expected event, keep in logoff state
102 std::make_pair(ACCOUNT_AUTHENTICATE_FAILED_EVT, nullptr),
103 // unexpected event, re-initial state machine, check the state from account server
104 std::make_pair(ACCOUNT_TOKEN_EXPIRED_EVT, nullptr),
105 // unexpected event, re-initial state machine, check the state from account server
106 std::make_pair(ACCOUNT_PASSWORD_CHANGED_EVT, nullptr),
107 // unexpected event, re-initial state machine, check the state from account server
108 std::make_pair(ACCOUNT_MANUAL_LOGOUT_EVT, nullptr),
109 // expected event, transform to logoff state
110 std::make_pair(ACCOUNT_MANUAL_UNBOUND_EVT, nullptr),
111 // expected event, transform to logoff state
112 std::make_pair(ACCOUNT_MANUAL_LOGOFF_EVT, nullptr)}
113 )
114 };
115 }
116
117 /**
118 * Account state machine clean.
119 */
Clean()120 void AccountStateMachine::Clean()
121 {
122 for (auto ¤tStateIter : stateMachineMap_) {
123 for (auto &eventIter : currentStateIter.second) {
124 if (eventIter.second != nullptr) {
125 delete eventIter.second;
126 eventIter.second = nullptr;
127 }
128 }
129 }
130 }
131
132 /**
133 * Process a state change event
134 *
135 * @param evt the event info
136 * @return true if the processing was completed, otherwise false
137 */
StateChangeProcess(int evt)138 bool AccountStateMachine::StateChangeProcess(int evt)
139 {
140 // for performance record
141 std::string stateRecordStr;
142 int64_t processTicks = GetTickCount();
143 stateRecordStr.append("state from[").append(std::to_string(currentState_)).append("] to [");
144
145 // get all the current state event action
146 auto stateIter = stateMachineMap_.find(currentState_);
147 if (stateIter == stateMachineMap_.end()) {
148 ACCOUNT_LOGE("current state %{public}d is not in state machine map.", currentState_);
149 return false;
150 }
151
152 // get the current event action
153 auto eventIter = stateIter->second.find(evt);
154 if (eventIter == stateIter->second.end()) {
155 ACCOUNT_LOGE("event %{public}d is not in state machine map.", evt);
156 return false;
157 }
158
159 // maybe action is null
160 if (eventIter->second == nullptr) {
161 ACCOUNT_LOGI("event %{public}d has no action.", evt);
162 return true;
163 }
164
165 int nextState = eventIter->second->GetNextState();
166 if (currentState_ != nextState) {
167 ACCOUNT_LOGI("account state change, (oldstate, newstate) = (%{public}d, %{public}d)", currentState_, nextState);
168 currentState_ = nextState;
169 }
170
171 // Record state change performance
172 processTicks = GetTickCount() - processTicks;
173 stateRecordStr.append(std::to_string(nextState)).append("], event[").append(std::to_string(evt)).append("] Cost");
174 PerfStat::GetInstance().SetAccountStateChangeTime(stateRecordStr, processTicks);
175
176 return true;
177 }
178 } // namespace AccountSA
179 } // namespace OHOS
180