1 /*
2 * Copyright (c) 2022-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
16 #include "fingerprint_auth_all_in_one_executor_hdi.h"
17
18 #include <cstdint>
19 #include <functional>
20 #include <map>
21 #include <memory>
22 #include <new>
23 #include <utility>
24 #include <vector>
25
26 #include "hdf_base.h"
27 #include "refbase.h"
28
29 #include "iam_check.h"
30 #include "iam_executor_framework_types.h"
31 #include "iam_logger.h"
32 #include "memory_guard.h"
33
34 #include "fingerprint_auth_defines.h"
35 #include "fingerprint_auth_executor_callback_hdi.h"
36 #include "fingerprint_auth_hdi.h"
37 #include "sa_command_manager.h"
38
39 #define LOG_TAG "FINGERPRINT_AUTH_SA"
40
41 namespace OHOS {
42 namespace UserIam {
43 namespace FingerprintAuth {
44 using IamResultCode = UserAuth::ResultCode;
45 using IamExecutorRole = UserAuth::ExecutorRole;
46 using IamExecutorInfo = UserAuth::ExecutorInfo;
47 namespace UserAuth = OHOS::UserIam::UserAuth;
FingerprintAllInOneExecutorHdi(sptr<IAllInOneExecutor> executorProxy)48 FingerprintAllInOneExecutorHdi::FingerprintAllInOneExecutorHdi(sptr<IAllInOneExecutor> executorProxy)
49 : executorProxy_(executorProxy) {};
50
GetExecutorInfo(IamExecutorInfo & info)51 IamResultCode FingerprintAllInOneExecutorHdi::GetExecutorInfo(IamExecutorInfo &info)
52 {
53 IF_FALSE_LOGE_AND_RETURN_VAL(executorProxy_ != nullptr, IamResultCode::GENERAL_ERROR);
54 ExecutorInfo localInfo = {};
55 int32_t status = executorProxy_->GetExecutorInfo(localInfo);
56 IamResultCode result = ConvertResultCode(status);
57 if (result != IamResultCode::SUCCESS) {
58 IAM_LOGE("GetExecutorInfo fail result %{public}d", result);
59 return result;
60 }
61 result = MoveHdiExecutorInfo(localInfo, info);
62 if (result != IamResultCode::SUCCESS) {
63 IAM_LOGE("MoveHdiExecutorInfo fail result %{public}d", result);
64 return result;
65 }
66 return IamResultCode::SUCCESS;
67 }
68
OnRegisterFinish(const std::vector<uint64_t> & templateIdList,const std::vector<uint8_t> & frameworkPublicKey,const std::vector<uint8_t> & extraInfo)69 IamResultCode FingerprintAllInOneExecutorHdi::OnRegisterFinish(const std::vector<uint64_t> &templateIdList,
70 const std::vector<uint8_t> &frameworkPublicKey, const std::vector<uint8_t> &extraInfo)
71 {
72 IF_FALSE_LOGE_AND_RETURN_VAL(executorProxy_ != nullptr, IamResultCode::GENERAL_ERROR);
73 int32_t status = executorProxy_->OnRegisterFinish(templateIdList, frameworkPublicKey, extraInfo);
74 IamResultCode result = ConvertResultCode(status);
75 if (result != IamResultCode::SUCCESS) {
76 IAM_LOGE("OnRegisterFinish fail result %{public}d", result);
77 return result;
78 }
79
80 result = RegisterSaCommandCallback();
81 if (result != IamResultCode::SUCCESS) {
82 IAM_LOGE("RegisterSaCommandCallback fail");
83 return result;
84 }
85 return IamResultCode::SUCCESS;
86 }
87
SendMessage(uint64_t scheduleId,int32_t srcRole,const std::vector<uint8_t> & msg)88 IamResultCode FingerprintAllInOneExecutorHdi::SendMessage(uint64_t scheduleId, int32_t srcRole,
89 const std::vector<uint8_t> &msg)
90 {
91 IF_FALSE_LOGE_AND_RETURN_VAL(executorProxy_ != nullptr, IamResultCode::GENERAL_ERROR);
92 int32_t status = executorProxy_->SendMessage(scheduleId, srcRole, msg);
93 IamResultCode result = ConvertResultCode(status);
94 if (result != IamResultCode::SUCCESS) {
95 IAM_LOGE("Authenticate fail result %{public}d", result);
96 return result;
97 }
98 return IamResultCode::SUCCESS;
99 }
100
Enroll(uint64_t scheduleId,const UserAuth::EnrollParam & param,const std::shared_ptr<UserAuth::IExecuteCallback> & callbackObj)101 IamResultCode FingerprintAllInOneExecutorHdi::Enroll(uint64_t scheduleId, const UserAuth::EnrollParam ¶m,
102 const std::shared_ptr<UserAuth::IExecuteCallback> &callbackObj)
103 {
104 IF_FALSE_LOGE_AND_RETURN_VAL(executorProxy_ != nullptr, IamResultCode::GENERAL_ERROR);
105 IF_FALSE_LOGE_AND_RETURN_VAL(callbackObj != nullptr, IamResultCode::GENERAL_ERROR);
106 sptr<IExecutorCallback> callback(
107 new (std::nothrow) FingerprintAuthExecutorCallbackHdi(callbackObj, FINGER_CALLBACK_ENROLL));
108 IF_FALSE_LOGE_AND_RETURN_VAL(callback != nullptr, IamResultCode::GENERAL_ERROR);
109 int32_t status = executorProxy_->Enroll(scheduleId, param.extraInfo, callback);
110 IamResultCode result = ConvertResultCode(status);
111 if (result != IamResultCode::SUCCESS) {
112 IAM_LOGE("Enroll fail result %{public}d", result);
113 return result;
114 }
115 return IamResultCode::SUCCESS;
116 }
117
Authenticate(uint64_t scheduleId,const UserAuth::AuthenticateParam & param,const std::shared_ptr<UserAuth::IExecuteCallback> & callbackObj)118 IamResultCode FingerprintAllInOneExecutorHdi::Authenticate(uint64_t scheduleId,
119 const UserAuth::AuthenticateParam ¶m, const std::shared_ptr<UserAuth::IExecuteCallback> &callbackObj)
120 {
121 IF_FALSE_LOGE_AND_RETURN_VAL(executorProxy_ != nullptr, IamResultCode::GENERAL_ERROR);
122 IF_FALSE_LOGE_AND_RETURN_VAL(callbackObj != nullptr, IamResultCode::GENERAL_ERROR);
123 sptr<IExecutorCallback> callback(
124 new (std::nothrow) FingerprintAuthExecutorCallbackHdi(callbackObj, FINGER_CALLBACK_AUTH));
125 IF_FALSE_LOGE_AND_RETURN_VAL(callback != nullptr, IamResultCode::GENERAL_ERROR);
126 int32_t status = executorProxy_->Authenticate(scheduleId, param.templateIdList, param.endAfterFirstFail,
127 param.extraInfo, callback);
128 IamResultCode result = ConvertResultCode(status);
129 if (result != IamResultCode::SUCCESS) {
130 IAM_LOGE("Authenticate fail result %{public}d", result);
131 return result;
132 }
133 return IamResultCode::SUCCESS;
134 }
135
Identify(uint64_t scheduleId,const UserAuth::IdentifyParam & param,const std::shared_ptr<UserAuth::IExecuteCallback> & callbackObj)136 IamResultCode FingerprintAllInOneExecutorHdi::Identify(uint64_t scheduleId, const UserAuth::IdentifyParam ¶m,
137 const std::shared_ptr<UserAuth::IExecuteCallback> &callbackObj)
138 {
139 IF_FALSE_LOGE_AND_RETURN_VAL(executorProxy_ != nullptr, IamResultCode::GENERAL_ERROR);
140 IF_FALSE_LOGE_AND_RETURN_VAL(callbackObj != nullptr, IamResultCode::GENERAL_ERROR);
141 sptr<IExecutorCallback> callback(
142 new (std::nothrow) FingerprintAuthExecutorCallbackHdi(callbackObj, FINGER_CALLBACK_IDENTIFY));
143 IF_FALSE_LOGE_AND_RETURN_VAL(callback != nullptr, IamResultCode::GENERAL_ERROR);
144 int32_t status = executorProxy_->Identify(scheduleId, param.extraInfo, callback);
145 IamResultCode result = ConvertResultCode(status);
146 if (result != IamResultCode::SUCCESS) {
147 IAM_LOGE("Identify fail result %{public}d", result);
148 return result;
149 }
150 return IamResultCode::SUCCESS;
151 }
152
Delete(const std::vector<uint64_t> & templateIdList)153 IamResultCode FingerprintAllInOneExecutorHdi::Delete(const std::vector<uint64_t> &templateIdList)
154 {
155 IF_FALSE_LOGE_AND_RETURN_VAL(executorProxy_ != nullptr, IamResultCode::GENERAL_ERROR);
156 int32_t status = executorProxy_->Delete(templateIdList);
157 IamResultCode result = ConvertResultCode(status);
158 if (result != IamResultCode::SUCCESS) {
159 IAM_LOGE("Delete fail result %{public}d", result);
160 return result;
161 }
162 return IamResultCode::SUCCESS;
163 }
164
Cancel(uint64_t scheduleId)165 IamResultCode FingerprintAllInOneExecutorHdi::Cancel(uint64_t scheduleId)
166 {
167 IF_FALSE_LOGE_AND_RETURN_VAL(executorProxy_ != nullptr, IamResultCode::GENERAL_ERROR);
168 int32_t status = executorProxy_->Cancel(scheduleId);
169 IamResultCode result = ConvertResultCode(status);
170 if (result != IamResultCode::SUCCESS) {
171 IAM_LOGE("Cancel fail result %{public}d", result);
172 return result;
173 }
174 return IamResultCode::SUCCESS;
175 }
176
SendCommand(UserAuth::PropertyMode commandId,const std::vector<uint8_t> & extraInfo,const std::shared_ptr<UserAuth::IExecuteCallback> & callbackObj)177 IamResultCode FingerprintAllInOneExecutorHdi::SendCommand(UserAuth::PropertyMode commandId,
178 const std::vector<uint8_t> &extraInfo, const std::shared_ptr<UserAuth::IExecuteCallback> &callbackObj)
179 {
180 IF_FALSE_LOGE_AND_RETURN_VAL(executorProxy_ != nullptr, IamResultCode::GENERAL_ERROR);
181 IF_FALSE_LOGE_AND_RETURN_VAL(callbackObj != nullptr, IamResultCode::GENERAL_ERROR);
182 int32_t hdiCommandId;
183 IamResultCode result = ConvertCommandId(commandId, hdiCommandId);
184 if (result != IamResultCode::SUCCESS) {
185 IAM_LOGE("ConvertCommandId fail result %{public}d", result);
186 return result;
187 }
188 sptr<IExecutorCallback> callback(
189 new (std::nothrow) FingerprintAuthExecutorCallbackHdi(callbackObj, FINGER_CALLBACK_COMMAND));
190 IF_FALSE_LOGE_AND_RETURN_VAL(callback != nullptr, IamResultCode::GENERAL_ERROR);
191 int32_t status = executorProxy_->SendCommand(hdiCommandId, extraInfo, callback);
192 result = ConvertResultCode(status);
193 if (result != IamResultCode::SUCCESS) {
194 IAM_LOGE("SendCommand fail result %{public}d", result);
195 return result;
196 }
197 return IamResultCode::SUCCESS;
198 }
199
GetProperty(const std::vector<uint64_t> & templateIdList,const std::vector<UserAuth::Attributes::AttributeKey> & keys,UserAuth::Property & property)200 UserAuth::ResultCode FingerprintAllInOneExecutorHdi::GetProperty(const std::vector<uint64_t> &templateIdList,
201 const std::vector<UserAuth::Attributes::AttributeKey> &keys, UserAuth::Property &property)
202 {
203 IF_FALSE_LOGE_AND_RETURN_VAL(executorProxy_ != nullptr, IamResultCode::GENERAL_ERROR);
204
205 std::vector<int32_t> propertyTypes;
206 IamResultCode result = ConvertAttributeKeyVectorToPropertyType(keys, propertyTypes);
207 IF_FALSE_LOGE_AND_RETURN_VAL(result == IamResultCode::SUCCESS, IamResultCode::GENERAL_ERROR);
208
209 Property hdiProperty;
210 int32_t status = executorProxy_->GetProperty(templateIdList, propertyTypes, hdiProperty);
211 result = ConvertResultCode(status);
212 if (result != IamResultCode::SUCCESS) {
213 IAM_LOGE("SendCommand fail result %{public}d", result);
214 return result;
215 }
216 MoveHdiProperty(hdiProperty, property);
217 return IamResultCode::SUCCESS;
218 }
219
SetCachedTemplates(const std::vector<uint64_t> & templateIdList)220 UserAuth::ResultCode FingerprintAllInOneExecutorHdi::SetCachedTemplates(const std::vector<uint64_t> &templateIdList)
221 {
222 IF_FALSE_LOGE_AND_RETURN_VAL(executorProxy_ != nullptr, IamResultCode::GENERAL_ERROR);
223
224 int32_t status = executorProxy_->SetCachedTemplates(templateIdList);
225 IamResultCode result = ConvertResultCode(status);
226 if (result != IamResultCode::SUCCESS) {
227 IAM_LOGE("SendCommand fail result %{public}d", result);
228 return result;
229 }
230 return IamResultCode::SUCCESS;
231 }
232
OnHdiDisconnect()233 void FingerprintAllInOneExecutorHdi::OnHdiDisconnect()
234 {
235 IAM_LOGE("start");
236 SaCommandManager::GetInstance().OnHdiDisconnect(shared_from_this());
237 }
238
MoveHdiExecutorInfo(ExecutorInfo & in,IamExecutorInfo & out)239 IamResultCode FingerprintAllInOneExecutorHdi::MoveHdiExecutorInfo(ExecutorInfo &in, IamExecutorInfo &out)
240 {
241 out.executorSensorHint = static_cast<uint32_t>(in.sensorId);
242 out.executorMatcher = in.executorMatcher;
243 IamResultCode result = ConvertExecutorRole(in.executorRole, out.executorRole);
244 if (result != IamResultCode::SUCCESS) {
245 IAM_LOGE("ConvertExecutorRole fail result %{public}d", result);
246 return result;
247 }
248 result = ConvertAuthType(in.authType, out.authType);
249 if (result != IamResultCode::SUCCESS) {
250 IAM_LOGE("ConvertAuthType fail result %{public}d", result);
251 return result;
252 }
253 result = ConvertExecutorSecureLevel(in.esl, out.esl);
254 if (result != IamResultCode::SUCCESS) {
255 IAM_LOGE("ConvertExecutorSecureLevel fail result %{public}d", result);
256 return result;
257 }
258 out.maxTemplateAcl = in.maxTemplateAcl;
259 in.publicKey.swap(out.publicKey);
260 return IamResultCode::SUCCESS;
261 }
262
MoveHdiProperty(Property & in,UserAuth::Property & out)263 void FingerprintAllInOneExecutorHdi::MoveHdiProperty(Property &in, UserAuth::Property &out)
264 {
265 out.authSubType = in.authSubType;
266 out.lockoutDuration = in.lockoutDuration;
267 out.remainAttempts = in.remainAttempts;
268 out.enrollmentProgress.swap(in.enrollmentProgress);
269 out.sensorInfo.swap(in.sensorInfo);
270 }
271
ConvertCommandId(const UserAuth::PropertyMode in,int32_t & out)272 IamResultCode FingerprintAllInOneExecutorHdi::ConvertCommandId(const UserAuth::PropertyMode in, int32_t &out)
273 {
274 if (static_cast<DriverCommandId>(in) > DriverCommandId::VENDOR_COMMAND_BEGIN) {
275 out = static_cast<DriverCommandId>(in);
276 IAM_LOGI("vendor command id %{public}d, no covert", out);
277 return IamResultCode::SUCCESS;
278 }
279
280 static const std::map<UserAuth::PropertyMode, DriverCommandId> data = {
281 { UserAuth::PropertyMode::PROPERTY_INIT_ALGORITHM, DriverCommandId::INIT_ALGORITHM },
282 { UserAuth::PropertyMode::PROPERTY_MODE_FREEZE, DriverCommandId::LOCK_TEMPLATE },
283 { UserAuth::PropertyMode::PROPERTY_MODE_UNFREEZE, DriverCommandId::UNLOCK_TEMPLATE } };
284 auto iter = data.find(in);
285 if (iter == data.end()) {
286 IAM_LOGE("command id %{public}d is invalid", in);
287 return IamResultCode::INVALID_PARAMETERS;
288 }
289 out = static_cast<int32_t>(iter->second);
290 IAM_LOGI("covert command id %{public}d to idl command is %{public}d", in, out);
291 return IamResultCode::SUCCESS;
292 }
293
ConvertAuthType(const int32_t in,UserAuth::AuthType & out)294 IamResultCode FingerprintAllInOneExecutorHdi::ConvertAuthType(const int32_t in, UserAuth::AuthType &out)
295 {
296 static const std::map<AuthType, UserAuth::AuthType> data = {
297 { AuthType::FINGERPRINT, UserAuth::AuthType::FINGERPRINT },
298 };
299 auto iter = data.find(static_cast<AuthType>(in));
300 if (iter == data.end()) {
301 IAM_LOGE("authType %{public}d is invalid", in);
302 return IamResultCode::GENERAL_ERROR;
303 }
304 out = iter->second;
305 return IamResultCode::SUCCESS;
306 }
307
ConvertExecutorRole(const int32_t in,IamExecutorRole & out)308 IamResultCode FingerprintAllInOneExecutorHdi::ConvertExecutorRole(const int32_t in, IamExecutorRole &out)
309 {
310 static const std::map<ExecutorRole, IamExecutorRole> data = {
311 { ExecutorRole::COLLECTOR, IamExecutorRole::COLLECTOR },
312 { ExecutorRole::VERIFIER, IamExecutorRole::VERIFIER },
313 { ExecutorRole::ALL_IN_ONE, IamExecutorRole::ALL_IN_ONE },
314 };
315 auto iter = data.find(static_cast<ExecutorRole>(in));
316 if (iter == data.end()) {
317 IAM_LOGE("executorRole %{public}d is invalid", in);
318 return IamResultCode::GENERAL_ERROR;
319 }
320 out = iter->second;
321 return IamResultCode::SUCCESS;
322 }
323
ConvertExecutorSecureLevel(const int32_t in,UserAuth::ExecutorSecureLevel & out)324 IamResultCode FingerprintAllInOneExecutorHdi::ConvertExecutorSecureLevel(const int32_t in,
325 UserAuth::ExecutorSecureLevel &out)
326 {
327 static const std::map<ExecutorSecureLevel, UserAuth::ExecutorSecureLevel> data = {
328 { ExecutorSecureLevel::ESL0, UserAuth::ExecutorSecureLevel::ESL0 },
329 { ExecutorSecureLevel::ESL1, UserAuth::ExecutorSecureLevel::ESL1 },
330 { ExecutorSecureLevel::ESL2, UserAuth::ExecutorSecureLevel::ESL2 },
331 { ExecutorSecureLevel::ESL3, UserAuth::ExecutorSecureLevel::ESL3 },
332 };
333 auto iter = data.find(static_cast<ExecutorSecureLevel>(in));
334 if (iter == data.end()) {
335 IAM_LOGE("executorSecureLevel %{public}d is invalid", in);
336 return IamResultCode::GENERAL_ERROR;
337 }
338 out = iter->second;
339 return IamResultCode::SUCCESS;
340 }
341
ConvertResultCode(const int32_t in)342 IamResultCode FingerprintAllInOneExecutorHdi::ConvertResultCode(const int32_t in)
343 {
344 HDF_STATUS hdfIn = static_cast<HDF_STATUS>(in);
345 static const std::map<HDF_STATUS, IamResultCode> data = {
346 { HDF_SUCCESS, IamResultCode::SUCCESS },
347 { HDF_FAILURE, IamResultCode::GENERAL_ERROR },
348 { HDF_ERR_TIMEOUT, IamResultCode::TIMEOUT },
349 { HDF_ERR_QUEUE_FULL, IamResultCode::BUSY },
350 { HDF_ERR_DEVICE_BUSY, IamResultCode::BUSY },
351 };
352
353 IamResultCode out;
354 auto iter = data.find(hdfIn);
355 if (iter == data.end()) {
356 out = IamResultCode::GENERAL_ERROR;
357 } else {
358 out = iter->second;
359 }
360 IAM_LOGI("covert hdi result code %{public}d to framework result code %{public}d", in, out);
361 return out;
362 }
363
ConvertAttributeKeyVectorToPropertyType(const std::vector<UserAuth::Attributes::AttributeKey> inItems,std::vector<int32_t> & outItems)364 IamResultCode FingerprintAllInOneExecutorHdi::ConvertAttributeKeyVectorToPropertyType(
365 const std::vector<UserAuth::Attributes::AttributeKey> inItems, std::vector<int32_t> &outItems)
366 {
367 outItems.clear();
368 for (auto &inItem : inItems) {
369 int32_t outItem;
370 IamResultCode result = ConvertAttributeKeyToPropertyType(inItem, outItem);
371 IF_FALSE_LOGE_AND_RETURN_VAL(result == IamResultCode::SUCCESS, IamResultCode::GENERAL_ERROR);
372 outItems.push_back(outItem);
373 }
374
375 return IamResultCode::SUCCESS;
376 }
377
ConvertAttributeKeyToPropertyType(const UserAuth::Attributes::AttributeKey in,int32_t & out)378 IamResultCode FingerprintAllInOneExecutorHdi::ConvertAttributeKeyToPropertyType(
379 const UserAuth::Attributes::AttributeKey in, int32_t &out)
380 {
381 static const std::map<UserAuth::Attributes::AttributeKey, GetPropertyType> data = {
382 { UserAuth::Attributes::ATTR_PIN_SUB_TYPE, GetPropertyType::AUTH_SUB_TYPE },
383 { UserAuth::Attributes::ATTR_FREEZING_TIME, GetPropertyType::LOCKOUT_DURATION },
384 { UserAuth::Attributes::ATTR_REMAIN_TIMES, GetPropertyType::REMAIN_ATTEMPTS },
385 { UserAuth::Attributes::ATTR_ENROLL_PROGRESS, GetPropertyType::ENROLL_PROGRESS },
386 { UserAuth::Attributes::ATTR_SENSOR_INFO, GetPropertyType::SENSOR_INFO },
387 };
388
389 auto iter = data.find(in);
390 if (iter == data.end()) {
391 IAM_LOGE("attribute %{public}d is invalid", in);
392 return IamResultCode::GENERAL_ERROR;
393 } else {
394 out = static_cast<int32_t>(iter->second);
395 }
396 IAM_LOGI("covert hdi result code %{public}d to framework result code %{public}d", in, out);
397 return IamResultCode::SUCCESS;
398 }
399
RegisterSaCommandCallback()400 UserAuth::ResultCode FingerprintAllInOneExecutorHdi::RegisterSaCommandCallback()
401 {
402 IF_FALSE_LOGE_AND_RETURN_VAL(executorProxy_ != nullptr, IamResultCode::GENERAL_ERROR);
403
404 sptr<SaCommandCallback> callback(new (std::nothrow) SaCommandCallback(shared_from_this()));
405 IF_FALSE_LOGE_AND_RETURN_VAL(callback != nullptr, IamResultCode::GENERAL_ERROR);
406
407 int32_t status = executorProxy_->RegisterSaCommandCallback(callback);
408 IamResultCode result = ConvertResultCode(status);
409 if (result != IamResultCode::SUCCESS) {
410 IAM_LOGE("RegisterSaCommandCallback fail result %{public}d", result);
411 return result;
412 }
413
414 return IamResultCode::SUCCESS;
415 }
416
OnSaCommands(const std::vector<SaCommand> & commands)417 int32_t FingerprintAllInOneExecutorHdi::SaCommandCallback::OnSaCommands(const std::vector<SaCommand> &commands)
418 {
419 IAM_LOGI("start");
420 MemoryGuard guard;
421 IamResultCode result = SaCommandManager::GetInstance().ProcessSaCommands(executorHdi_, commands);
422 if (result != IamResultCode::SUCCESS) {
423 IAM_LOGE("ProcessSaCommands fail");
424 return HDF_FAILURE;
425 }
426 IAM_LOGI("success");
427 return HDF_SUCCESS;
428 };
429 } // namespace FingerprintAuth
430 } // namespace UserIam
431 } // namespace OHOS
432