1 /*
2 * Copyright (c) 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 "async_command_base.h"
17
18 #include <atomic>
19 #include <cstdint>
20 #include <ostream>
21 #include <sstream>
22 #include <string>
23 #include <vector>
24
25 #include "iam_check.h"
26 #include "iam_defines.h"
27 #include "iam_logger.h"
28 #include "iam_para2str.h"
29 #include "iam_executor_framework_types.h"
30
31 #define LOG_TAG "USER_AUTH_EXECUTOR"
32
33 namespace OHOS {
34 namespace UserIam {
35 namespace UserAuth {
AsyncCommandBase(std::string type,uint64_t scheduleId,std::weak_ptr<Executor> executor,std::shared_ptr<ExecutorMessenger> executorMessenger)36 AsyncCommandBase::AsyncCommandBase(std::string type, uint64_t scheduleId, std::weak_ptr<Executor> executor,
37 std::shared_ptr<ExecutorMessenger> executorMessenger)
38 : scheduleId_(scheduleId),
39 executor_(executor),
40 executorMessenger_(executorMessenger)
41 {
42 auto commandId = GenerateCommandId();
43 std::ostringstream ss;
44 ss << "Command(type:" << type << ", id:" << commandId << ", scheduleId:" << GET_MASKED_STRING(scheduleId_) << ")";
45 description_ = ss.str();
46 }
47
OnHdiDisconnect()48 void AsyncCommandBase::OnHdiDisconnect()
49 {
50 IAM_LOGI("driver disconnect, %{public}s end process", GetDescription());
51 // Need new result code: hal invalid
52 OnResult(ResultCode::GENERAL_ERROR);
53 }
54
StartProcess()55 ResultCode AsyncCommandBase::StartProcess()
56 {
57 IAM_LOGI("%{public}s start process", GetDescription());
58 auto executor = executor_.lock();
59 if (executor == nullptr) {
60 IAM_LOGE("%{public}s executor has been released, start process fail", GetDescription());
61 return ResultCode::GENERAL_ERROR;
62 }
63 executor->AddCommand(shared_from_this());
64 ResultCode ret = SendRequest();
65 if (ret != ResultCode::SUCCESS) {
66 IAM_LOGE("%{public}s send request failed", GetDescription());
67 EndProcess();
68 return ret;
69 }
70 return ResultCode::SUCCESS;
71 }
72
OnResult(ResultCode result)73 void AsyncCommandBase::OnResult(ResultCode result)
74 {
75 std::vector<uint8_t> extraInfo;
76 OnResult(result, extraInfo);
77 }
78
OnResult(ResultCode result,const std::vector<uint8_t> & extraInfo)79 void AsyncCommandBase::OnResult(ResultCode result, const std::vector<uint8_t> &extraInfo)
80 {
81 std::lock_guard<std::mutex> guard(mutex_);
82 if (isFinished_) {
83 IAM_LOGE("command is finished, invocation of OnResult is invalid");
84 return;
85 }
86 isFinished_ = true;
87 OnResultInner(result, extraInfo);
88 EndProcess();
89 }
90
OnAcquireInfo(int32_t acquire,const std::vector<uint8_t> & extraInfo)91 void AsyncCommandBase::OnAcquireInfo(int32_t acquire, const std::vector<uint8_t> &extraInfo)
92 {
93 std::lock_guard<std::mutex> guard(mutex_);
94 if (isFinished_) {
95 IAM_LOGE("command is finished, invocation of OnAcquireInfo is invalid");
96 return;
97 }
98 OnAcquireInfoInner(acquire, extraInfo);
99 }
100
OnAcquireInfoInner(int32_t acquire,const std::vector<uint8_t> & extraInfo)101 void AsyncCommandBase::OnAcquireInfoInner(int32_t acquire, const std::vector<uint8_t> &extraInfo)
102 {
103 IAM_LOGI("%{public}s start", GetDescription());
104
105 Attributes attr;
106 bool setAcquireRet = attr.SetInt32Value(Attributes::ATTR_TIP_INFO, acquire);
107 IF_FALSE_LOGE_AND_RETURN(setAcquireRet);
108 bool setExtraInfoRet = attr.SetUint8ArrayValue(Attributes::ATTR_EXTRA_INFO, extraInfo);
109 IF_FALSE_LOGE_AND_RETURN(setExtraInfoRet);
110
111 auto data = AuthMessage::As(attr.Serialize());
112 IF_FALSE_LOGE_AND_RETURN(data != nullptr);
113 int32_t ret = MessengerSendData(scheduleId_, SCHEDULER, data);
114 if (ret != USERAUTH_SUCCESS) {
115 IAM_LOGE("%{public}s call SendData fail", GetDescription());
116 return;
117 }
118 IAM_LOGI("%{public}s end, acquire %{public}d", GetDescription(), acquire);
119 }
120
OnMessage(int destRole,const std::vector<uint8_t> & msg)121 void AsyncCommandBase::OnMessage(int destRole, const std::vector<uint8_t> &msg)
122 {
123 std::lock_guard<std::mutex> guard(mutex_);
124 if (isFinished_) {
125 IAM_LOGE("command is finished, invocation of OnMessage is invalid");
126 return;
127 }
128 OnMessageInner(destRole, msg);
129 }
130
OnMessageInner(int destRole,const std::vector<uint8_t> & msg)131 void AsyncCommandBase::OnMessageInner(int destRole, const std::vector<uint8_t> &msg)
132 {
133 IAM_LOGI("%{public}s start", GetDescription());
134
135 std::shared_ptr<Executor> executor = executor_.lock();
136 IF_FALSE_LOGE_AND_RETURN(executor != nullptr);
137
138 Attributes attr;
139 bool setAcquireRet = attr.SetInt32Value(Attributes::ATTR_SRC_ROLE, executor->GetExecutorRole());
140 IF_FALSE_LOGE_AND_RETURN(setAcquireRet);
141 bool setExtraInfoRet = attr.SetUint8ArrayValue(Attributes::ATTR_EXTRA_INFO, msg);
142 IF_FALSE_LOGE_AND_RETURN(setExtraInfoRet);
143
144 auto data = AuthMessage::As(attr.Serialize());
145 IF_FALSE_LOGE_AND_RETURN(data != nullptr);
146 int32_t ret = MessengerSendData(scheduleId_, static_cast<ExecutorRole>(destRole), data);
147 if (ret != USERAUTH_SUCCESS) {
148 IAM_LOGE("%{public}s call SendData fail", GetDescription());
149 return;
150 }
151 IAM_LOGI("%{public}s end, msg size %{public}zu", GetDescription(), msg.size());
152 }
153
GetAuthType()154 int32_t AsyncCommandBase::GetAuthType()
155 {
156 auto executor = executor_.lock();
157 if (executor == nullptr) {
158 IAM_LOGE("%{public}s executor has been released, get executor type fail", GetDescription());
159 return INVALID_AUTH_TYPE;
160 }
161 return executor->GetAuthType();
162 }
163
EndProcess()164 void AsyncCommandBase::EndProcess()
165 {
166 IAM_LOGI("%{public}s end process", GetDescription());
167 auto executor = executor_.lock();
168 if (executor == nullptr) {
169 IAM_LOGI(
170 "%{public}s executor has been released, command has been removed, no need remove again", GetDescription());
171 return;
172 }
173 executor->RemoveCommand(shared_from_this());
174 }
175
GetDescription()176 const char *AsyncCommandBase::GetDescription()
177 {
178 return description_.c_str();
179 }
180
GenerateCommandId()181 uint32_t AsyncCommandBase::GenerateCommandId()
182 {
183 std::atomic<uint32_t> commandId = 0;
184 // commandId is only used in log, uint32 overflow or duplicate is ok
185 return ++commandId;
186 }
187
GetExecutorHdi()188 std::shared_ptr<IAuthExecutorHdi> AsyncCommandBase::GetExecutorHdi()
189 {
190 auto executor = executor_.lock();
191 if (executor == nullptr) {
192 IAM_LOGE("%{public}s executor has been released, get executor hdi fail", GetDescription());
193 return nullptr;
194 }
195 return executor->GetExecutorHdi();
196 }
197
MessengerSendData(uint64_t scheduleId,ExecutorRole dstType,std::shared_ptr<AuthMessage> msg)198 int32_t AsyncCommandBase::MessengerSendData(uint64_t scheduleId,
199 ExecutorRole dstType, std::shared_ptr<AuthMessage> msg)
200 {
201 auto messenger = executorMessenger_;
202 IF_FALSE_LOGE_AND_RETURN_VAL(messenger != nullptr, USERAUTH_ERROR);
203 return messenger->SendData(scheduleId, dstType, msg);
204 }
205
MessengerFinish(uint64_t scheduleId,int32_t resultCode,std::shared_ptr<Attributes> finalResult)206 int32_t AsyncCommandBase::MessengerFinish(uint64_t scheduleId, int32_t resultCode,
207 std::shared_ptr<Attributes> finalResult)
208 {
209 auto messenger = executorMessenger_;
210 IF_FALSE_LOGE_AND_RETURN_VAL(messenger != nullptr, USERAUTH_ERROR);
211 int32_t ret = messenger->Finish(scheduleId, resultCode, *finalResult);
212 executorMessenger_ = nullptr;
213 return ret;
214 }
215 } // namespace UserAuth
216 } // namespace UserIam
217 } // namespace OHOS
218