1# Fingerprint_auth
2
3## 概述
4
5### 功能简介
6
7指纹认证是端侧设备不可或缺的功能,为设备提供用户认证能力,可应用于设备解锁、支付、应用登录等身份认证场景。用户注册指纹后,指纹认证模块就可为设备提供指纹认证的功能。指纹认证功能整体框架如图1。
8
9基于HDF(Hardware Driver Foundation)驱动框架开发的Fingerprint_auth驱动,能够屏蔽硬件器件差异,为上层用户认证框架和Fingerprint_auth服务提供稳定的指纹认证基础能力接口,包括指纹认证执行器列表查询、执行器信息查询、指定指纹模板ID查询模板信息、用户认证框架和执行器间的指纹模板信息对账、指纹的录入、删除、认证和识别等。
10
11**图1** 指纹认证功能整体框架
12
13![image](figures/指纹认证功能整体框架图.png "指纹认证功能整体框架图")
14
15### 基本概念
16
17用户认证框架与各基础认证服务组成的身份认证系统支持用户认证凭据设置、删除、认证等基础功能。系统支持用户身份认证,需要提供数据采集、处理、存储及比对能力。
18- 执行器
19
20  执行器是能够提供以上能力的处理模块,各基础认证服务提供执行器能力,被身份认证框架调度完成各项基础能力。
21
22- 执行器安全等级
23
24  执行器提供能力时所在运行环境达到的安全级别。
25
26- 执行器角色
27
28  - 全功能执行器:执行器可独立处理一次凭据注册和身份认证请求,即可提供用户认证数据采集、处理、储存及比对能力。
29
30  - 采集器:执行器提供用户认证时的数据采集能力,需要和认证器配合完成用户认证。
31
32  - 认证器:认证器提供用户认证时数据处理能力,读取存储的凭据模板与当前认证信息完成比对。
33
34- 执行器类型
35
36  同一种身份认证类型的不同认证方式会产生认证算法差异,设备器件差异也会导致算法差异,执行器根据支持的算法类型差异或对接的器件差异,会定义不同的执行器类型。
37
38- 用户认证框架公钥 & 执行器公钥
39
40  用户身份认证处理需要保证用户数据安全以及认证结果的准确性,用户认证框架与基础认证服务间的关键交互信息需要做数据完整性保护,各基础认证服务将提供的执行器能力对接到用户认证框架时,需要交换各自的公钥,其中:
41
42    1)执行器通过用户认证框架公钥校验调度指令的准确性。
43
44    2)执行器公钥可被用户认证框架用于校验认证结果的准确性,同时用于执行器交互认证时的校验交互信息的完整性。
45
46- 认证凭据
47
48  在用户设置认证凭据时认证服务会产生并存储认证凭据,每个模板有一个ID,用于索引模板信息文件,在认证时读取模板信息并用于与当次认证过程中产生的认证数据做对比,完成身份认证。
49
50- 执行器对账
51
52  用户认证框架统一管理用户身份和凭据ID的映射关系,执行器对接到用户认证框架时,会读取用户身份认证框架内保存的该执行器的模板ID列表,执行器需要与自己维护的模板ID列表进行比对,并删除冗余信息。
53
54- HAPs
55
56  HAPs(Harmony Ability Packages),广义上指可以安装在OpenHarmony上的应用包,本章节中仅代表Fingerprint_auth驱动的上层应用。
57
58- IDL接口
59
60  接口定义语言(Interface Definition Language)通过IDL编译器编译后,能够生成与编程语言相关的文件:客户端桩文件,服务器框架文件。本文主要是通过IDL接口生成的客户端和服务端来实现Fingerprint_auth服务和驱动的通信,详细使用方法可参考[IDL简介](https://gitee.com/openharmony/ability_idl_tool/blob/master/README.md)61
62- IPC通信
63
64  IPC(Inter Process Communication),进程间通信是指两个进程的数据之间产生交互,详细原理可参考[IPC通信简介](https://gitee.com/openharmony/communication_ipc/blob/master/README_zh.md)65
66- HDI
67
68  HDI(Hardware Device Interface),硬件设备接口,位于基础系统服务层和设备驱动层之间,是提供给硬件系统服务开发者使用的、统一的硬件设备功能抽象接口,其目的是为系统服务屏蔽底层硬件设备差异,具体可参考[HDI规范](../../design/hdi-design-specifications.md)。
69
70### 运作机制
71
72Fingerprint_auth驱动的主要工作是为上层用户认证框架和Fingerprint_auth服务提供稳定的指纹认证基础能力,保证设备上指纹认证功能可以正常运行。如图2,Fingerprint_auth服务通过执行器列表接口获取执行器信息后,向用户认证框架注册执行器。Fingerprint_auth服务通过执行器功能接口实现和Fingerprint_auth驱动的认证、识别、查询等功能的信息交互。
73开发者可基于HDF框架对不同芯片进行各自驱动的开发及HDI层接口的调用。
74
75**图2** Fingerprint_auth服务和Fingerprint_auth驱动交互
76
77![image](figures/指纹认证服务和驱动接口.png "指纹认证服务和驱动接口")
78
79### 约束与限制
80
81要求设备上具有可信执行环境TEE(Trusted Execution Environment),指纹特征信息高强度加密保存在可信执行环境中。
82
83## 开发指导
84
85### 场景介绍
86
87Fingerprint_auth驱动的主要工作是为上层用户认证框架和Fingerprint_auth服务提供稳定的指纹认证基础能力,保证设备上指纹认证功能可以正常运行。为实现上述场景的功能,开发者首先需要基于HDF驱动框架,完成Fingerprint_auth驱动开发,其次实现获取执行器列表接口和认证、识别查询等功能接口。
88
89### 接口说明
90
91注:以下接口列举的为IDL接口描述生成的对应C++语言函数接口,接口声明见idl文件(/drivers/interface/fingerprint_auth)。
92在本文中,指纹凭据的录入、认证、识别和删除相关的HDI接口如表1所示,表2中的回调函数分别用于指纹执行器返回操作结果给框架和返回操作过程中的提示信息给上层应用。
93
94**表1** 接口功能介绍
95
96| 接口名称        | 功能介绍         |
97| -------------------------------- | ----------------------------------- |
98| GetExecutorList(std::vector\<sptr\<IAllInOneExecutor>>& allInOneExecutors) | 获取V2_0版本执行器列表。 |
99| GetExecutorInfo(ExecutorInfo &executorInfo) | 获取执行器信息,包括执行器类型、执行器角色、认证类型、安全等级、执行器公钥等信息,用于向用户认证框架注册执行器。 |
100| OnRegisterFinish(const std::vector\<uint64_t>& templateIdList,<br/>        const std::vector\<uint8_t>& frameworkPublicKey, const std::vector\<uint8_t>& extraInfo) | 执行器注册成功后,获取用户认证框架的公钥信息;获取用户认证框架的模板列表用于对账。 |
101| Enroll(uint64_t scheduleId, const std::vector\<uint8_t>& extraInfo,<br/>        const sptr\<IExecutorCallback>& callbackObj) | 录入指纹模板。                                               |
102| Authenticate(uint64_t scheduleId, const std::vector\<uint64_t>& templateIdList, bool endAfterFirstFail,<br/>const std::vector\<uint8_t>& extraInfo, const sptr\<IExecutorCallback>& callbackObj) | 认证指纹模板(V2_0版本)。         |
103| Identify(uint64_t scheduleId, const std::vector\<uint8_t>& extraInfo,<br/>        const sptr\<IExecutorCallback>& callbackObj) | 识别指纹模板。           |
104| Delete(const std::vector\<uint64_t>& templateIdList)          | 删除指纹模板。        |
105| Cancel(uint64_t scheduleId)     | 通过scheduleId取消指定录入、认证、识别操作。     |
106| SendCommand(int32_t commandId, const std::vector\<uint8_t>& extraInfo,<br/>        const sptr\<IExecutorCallback>& callbackObj) | 指纹认证服务向Fingerprint_auth驱动传递参数的通用接口。       |
107| GetProperty(const std::vector\<uint64_t>& templateIdList,<br/>const std::vector\<int32_t>& propertyTypes, Property& property) | 获取执行器属性信息。 |
108| SetCachedTemplates(const std::vector\<uint64_t\> &templateIdList) | 设置需缓存模板列表。 |
109| RegisterSaCommandCallback(const sptr\<ISaCommandCallback\> &callbackObj) | 注册SA命令回调。 |
110
111**表2** 回调函数介绍
112
113| 接口名称                                                       | 功能介绍                 |
114| ------------------------------------------------------------ | ------------------------ |
115| IExecutorCallback::OnResult(int32_t result, const std::vector\<uint8_t>& extraInfo) | 返回操作的最终结果。     |
116| IExecutorCallback::OnTip(int32_t tip, const std::vector\<uint8_t>& extraInfo) | 返回操作的过程交互信息。 |
117| ISaCommandCallback::OnSaCommands(const std::vector\<SaCommand>& commands) | 发送命令列表。 |
118
119### 开发步骤
120
121以Hi3516DV300平台为例,我们提供了Fingerprint_auth驱动DEMO实例,以下是目录结构及各部分功能简介。
122
123```undefined
124// drivers/peripheral/fingerprint_auth
125├── BUILD.gn     # 编译脚本
126├── bundle.json  # 组件描述文件
127└── hdi_service  # Fingerprint_auth驱动实现
128    ├── BUILD.gn    # 编译脚本
129    ├── include     # 头文件
130    └── src         # 源文件
131        ├── executor_impl.cpp                       # 认证、录入等功能接口实现
132        ├── fingerprint_auth_interface_driver.cpp   # Fingerprint_auth驱动入口
133        └── fingerprint_auth_interface_service.cpp  # 获取执行器列表接口实现
134```
135
136下面结合DEMO实例介绍驱动开发的具体步骤。
137
1381. Fingerprint_auth驱动是基于HDF驱动框架设计,所以开发者需要按照驱动Driver Entry程序,完成Fingerprint_auth驱动框架开发,主要由Bind、Init、Release、Dispatch函数接口实现。关键代码如下,详细代码请参见[fingerprint_auth_interface_driver.cpp](https://gitee.com/openharmony/drivers_peripheral/blob/master/fingerprint_auth/hdi_service/src/fingerprint_auth_interface_driver.cpp)文件。
139
140   ```c++
141   // 通过自定义的HdfFingerprintAuthInterfaceHost对象包含ioService对象和真正的HDI Service实现IRemoteObject对象
142   struct HdfFingerprintAuthInterfaceHost {
143       struct IDeviceIoService ioService;
144       OHOS::sptr<OHOS::IRemoteObject> stub;
145   };
146
147   // 服务接口调用响应接口
148   static int32_t FingerprintAuthInterfaceDriverDispatch(struct HdfDeviceIoClient *client, int cmdId, struct HdfSBuf *data,
149       struct HdfSBuf *reply)
150   {
151       auto *hdfFingerprintAuthInterfaceHost = CONTAINER_OF(client->device->service, struct HdfFingerprintAuthInterfaceHost, ioService);
152
153       OHOS::MessageParcel *dataParcel = nullptr;
154       OHOS::MessageParcel *replyParcel = nullptr;
155       OHOS::MessageOption option;
156
157       if (SbufToParcel(data, &dataParcel) != HDF_SUCCESS) {
158           HDF_LOGE("%{public}s: invalid data sbuf object to dispatch", __func__);
159           return HDF_ERR_INVALID_PARAM;
160       }
161       if (SbufToParcel(reply, &replyParcel) != HDF_SUCCESS) {
162           HDF_LOGE("%{public}s: invalid reply sbuf object to dispatch", __func__);
163           return HDF_ERR_INVALID_PARAM;
164       }
165
166       return hdfFingerprintAuthInterfaceHost->stub->SendRequest(cmdId, *dataParcel, *replyParcel, option);
167   }
168
169   // 初始化接口
170   static int HdfFingerprintAuthInterfaceDriverInit(struct HdfDeviceObject *deviceObject)
171   {
172       HDF_LOGI("%{public}s: driver init start", __func__);
173       return HDF_SUCCESS;
174   }
175
176   // Fingerprint_auth驱动对外提供的服务绑定到HDF框架
177   static int HdfFingerprintAuthInterfaceDriverBind(struct HdfDeviceObject *deviceObject)
178   {
179       HDF_LOGI("%{public}s: driver bind start", __func__);
180       auto *hdfFingerprintAuthInterfaceHost = new (std::nothrow) HdfFingerprintAuthInterfaceHost;
181       if (hdfFingerprintAuthInterfaceHost == nullptr) {
182           HDF_LOGE("%{public}s: failed to create create HdfFingerprintAuthInterfaceHost object", __func__);
183           return HDF_FAILURE;
184       }
185
186       hdfFingerprintAuthInterfaceHost->ioService.Dispatch = FingerprintAuthInterfaceDriverDispatch;
187       hdfFingerprintAuthInterfaceHost->ioService.Open = NULL;
188       hdfFingerprintAuthInterfaceHost->ioService.Release = NULL;
189
190       auto serviceImpl = OHOS::HDI::FingerprintAuth::V2_0::IFingerprintAuthInterface::Get(true);
191       if (serviceImpl == nullptr) {
192           HDF_LOGE("%{public}s: failed to get of implement service", __func__);
193           delete hdfFingerprintAuthInterfaceHost;
194           return HDF_FAILURE;
195       }
196
197       hdfFingerprintAuthInterfaceHost->stub = OHOS::HDI::ObjectCollector::GetInstance().GetOrNewObject(serviceImpl,
198           OHOS::HDI::FingerprintAuth::V2_0::IFingerprintAuthInterface::GetDescriptor());
199       if (hdfFingerprintAuthInterfaceHost->stub == nullptr) {
200           HDF_LOGE("%{public}s: failed to get stub object", __func__);
201           delete hdfFingerprintAuthInterfaceHost;
202           return HDF_FAILURE;
203       }
204
205       deviceObject->service = &hdfFingerprintAuthInterfaceHost->ioService;
206       return HDF_SUCCESS;
207   }
208
209   // 释放Fingerprint_auth驱动中的资源
210   static void HdfFingerprintAuthInterfaceDriverRelease(struct HdfDeviceObject *deviceObject)
211   {
212       HDF_LOGI("%{public}s: driver release start", __func__);
213       if (deviceObject->service == nullptr) {
214           return;
215       }
216       auto *hdfFingerprintAuthInterfaceHost = CONTAINER_OF(deviceObject->service, struct HdfFingerprintAuthInterfaceHost, ioService);
217       if (hdfFingerprintAuthInterfaceHost != nullptr) {
218           delete hdfFingerprintAuthInterfaceHost;
219       }
220   }
221
222   // 注册Fingerprint_auth驱动入口数据结构体对象
223   struct HdfDriverEntry g_fingerprintAuthInterfaceDriverEntry = {
224       .moduleVersion = 1,
225       .moduleName = "drivers_peripheral_fingerprint_auth",
226       .Bind = HdfFingerprintAuthInterfaceDriverBind,
227       .Init = HdfFingerprintAuthInterfaceDriverInit,
228       .Release = HdfFingerprintAuthInterfaceDriverRelease,
229   };
230
231   // 调用HDF_INIT将驱动入口注册到HDF框架中。在加载驱动时HDF框架会先调用Bind函数,再调用Init函数加载该驱动。当Init调用异常时,HDF框架会调用Release释放驱动资源并退出
232   HDF_INIT(g_fingerprintAuthInterfaceDriverEntry);
233   ```
234
2352. Fingerprint_auth驱动框架开发完成后,Fingerprint_auth驱动需要向Fingerprint_auth服务和统一身份认证注册执行器,所以需要实现获取执行器列表接口。关键代码如下,详细代码请参见[fingerprint_auth_interface_service.cpp](https://gitee.com/openharmony/drivers_peripheral/blob/master/fingerprint_auth/hdi_service/src/fingerprint_auth_interface_service.cpp)文件。
236
237   ```c++
238   // 执行器实现类
239   class AllInOneExecutorImpl : public IAllInOneExecutor {
240   public:
241       AllInOneExecutorImpl(struct ExecutorInfo executorInfo);
242       virtual ~AllInOneExecutorImpl() {}
243
244   private:
245       struct ExecutorInfo executorInfo_; // 执行器信息
246   };
247
248   static constexpr uint16_t SENSOR_ID = 123; // 执行器sensorID
249   static constexpr uint32_t EXECUTOR_TYPE = 123; // 执行器类型
250   static constexpr size_t PUBLIC_KEY_LEN = 32; // 执行器32字节公钥
251
252   // 创建HDI服务对象
253   extern "C" IFingerprintAuthInterface *FingerprintAuthInterfaceImplGetInstance(void)
254   {
255       auto fingerprintAuthInterfaceService = new (std::nothrow) FingerprintAuthInterfaceService();
256       if (fingerprintAuthInterfaceService == nullptr) {
257           IAM_LOGE("fingerprintAuthInterfaceService is nullptr");
258           return nullptr;
259       }
260       return fingerprintAuthInterfaceService;
261   }
262
263   // 获取V2_0执行器列表实现
264   int32_t FingerprintAuthInterfaceService::GetExecutorList(std::vector<sptr<IAllInOneExecutor>> &executorList)
265   {
266       IAM_LOGI("interface mock start");
267       for (auto executor : executorList_) {
268           executorList.push_back(executor);
269       }
270       IAM_LOGI("interface mock success");
271       return HDF_SUCCESS;
272   }
273   ```
274
2753. 步骤1、2完成后基本实现了Fingerprint_auth驱动和Fingerprint_auth服务对接。接下来需实现执行器每个功能接口,来完成指纹认证基础能力。关键代码如下,详细代码请参见[all_in_one_executor_impl.cpp](https://gitee.com/openharmony/drivers_peripheral/blob/master/fingerprint_auth/hdi_service/src/all_in_one_executor_impl.cpp)文件。
276
277   ```c++
278   // 实现获取执行器信息接口
279   int32_t AllInOneExecutorImpl::GetExecutorInfo(ExecutorInfo &executorInfo)
280   {
281       IAM_LOGI("interface mock start");
282       executorInfo = executorInfo_;
283       IAM_LOGI("get executor information success");
284       return HDF_SUCCESS;
285   }
286
287   // 实现执行器注册成功后,获取用户认证框架的公钥信息、获取用户认证框架的模板列表接口。将公钥信息保持,模板列表用于和本地的模板做对账
288   int32_t AllInOneExecutorImpl::OnRegisterFinish(const std::vector<uint64_t> &templateIdList,
289       const std::vector<uint8_t> &frameworkPublicKey, const std::vector<uint8_t> &extraInfo)
290   {
291       IAM_LOGI("interface mock start");
292       static_cast<void>(templateIdList);
293       static_cast<void>(extraInfo);
294       static_cast<void>(frameworkPublicKey);
295       IAM_LOGI("register finish");
296       return HDF_SUCCESS;
297   }
298
299   // 实现指纹录入接口
300   int32_t AllInOneExecutorImpl::Enroll(
301       uint64_t scheduleId, const std::vector<uint8_t> &extraInfo, const sptr<IExecutorCallback> &callbackObj)
302   {
303       IAM_LOGI("interface mock start");
304       static_cast<void>(scheduleId);
305       static_cast<void>(extraInfo);
306       if (callbackObj == nullptr) {
307           IAM_LOGE("callbackObj is nullptr");
308           return HDF_ERR_INVALID_PARAM;
309       }
310       IAM_LOGI("enroll, result is %{public}d", ResultCode::OPERATION_NOT_SUPPORT);
311       int32_t ret = callbackObj->OnResult(ResultCode::OPERATION_NOT_SUPPORT, {});
312       if (ret != HDF_SUCCESS) {
313           IAM_LOGE("callback result is %{public}d", ret);
314           return HDF_FAILURE;
315       }
316       return HDF_SUCCESS;
317   }
318
319   // 实现指纹认证接口
320   int32_t AllInOneExecutorService::Authenticate(uint64_t scheduleId, const std::vector<uint64_t> &templateIdList,
321       const std::vector<uint8_t> &extraInfo, const sptr<IExecutorCallback> &callbackObj)
322   {
323       IAM_LOGI("interface mock start");
324       static_cast<void>(scheduleId);
325       static_cast<void>(templateIdList);
326       static_cast<void>(extraInfo);
327       if (callbackObj == nullptr) {
328           IAM_LOGE("callbackObj is nullptr");
329           return HDF_ERR_INVALID_PARAM;
330       }
331       IAM_LOGI("authenticate, result is %{public}d", ResultCode::NOT_ENROLLED);
332       int32_t ret = callbackObj->OnResult(ResultCode::NOT_ENROLLED, {});
333       if (ret != HDF_SUCCESS) {
334           IAM_LOGE("callback result is %{public}d", ret);
335           return HDF_FAILURE;
336       }
337       return HDF_SUCCESS;
338   }
339
340   // 实现指纹识别接口
341   int32_t AllInOneExecutorService::Identify(
342       uint64_t scheduleId, const std::vector<uint8_t> &extraInfo, const sptr<IExecutorCallback> &callbackObj)
343   {
344       IAM_LOGI("interface mock start");
345       static_cast<void>(scheduleId);
346       static_cast<void>(extraInfo);
347       if (callbackObj == nullptr) {
348           IAM_LOGE("callbackObj is nullptr");
349           return HDF_ERR_INVALID_PARAM;
350       }
351       IAM_LOGI("identify, result is %{public}d", ResultCode::OPERATION_NOT_SUPPORT);
352       int32_t ret = callbackObj->OnResult(ResultCode::OPERATION_NOT_SUPPORT, {});
353       if (ret != HDF_SUCCESS) {
354           IAM_LOGE("callback result is %{public}d", ret);
355           return HDF_FAILURE;
356       }
357       return HDF_SUCCESS;
358   }
359
360   // 实现删除指纹模板接口
361   int32_t AllInOneExecutorService::Delete(const std::vector<uint64_t> &templateIdList)
362   {
363       IAM_LOGI("interface mock start");
364       static_cast<void>(templateIdList);
365       IAM_LOGI("delete success");
366       return HDF_SUCCESS;
367   }
368
369   // 实现通过scheduleId取消指定操作接口
370   int32_t AllInOneExecutorService::Cancel(uint64_t scheduleId)
371   {
372       IAM_LOGI("interface mock start");
373       static_cast<void>(scheduleId);
374       IAM_LOGI("cancel success");
375       return HDF_SUCCESS;
376   }
377
378   // 实现指纹认证服务向Fingerprint_auth驱动传递参数的通用接口,当前需要实现冻结与解锁模板命令
379   int32_t AllInOneExecutorService::SendCommand(
380       int32_t commandId, const std::vector<uint8_t> &extraInfo, const sptr<IExecutorCallback> &callbackObj)
381   {
382       IAM_LOGI("interface mock start");
383       static_cast<void>(extraInfo);
384       if (callbackObj == nullptr) {
385           IAM_LOGE("callbackObj is nullptr");
386           return HDF_ERR_INVALID_PARAM;
387       }
388       int32_t ret;
389       switch (commandId) {
390           case DriverCommandId::LOCK_TEMPLATE:
391               IAM_LOGI("lock template, result is %{public}d", ResultCode::SUCCESS);
392               ret = callbackObj->OnResult(ResultCode::SUCCESS, {});
393               if (ret != HDF_SUCCESS) {
394                   IAM_LOGE("callback result is %{public}d", ret);
395                   return HDF_FAILURE;
396               }
397               break;
398           case DriverCommandId::UNLOCK_TEMPLATE:
399               IAM_LOGI("unlock template, result is %{public}d", ResultCode::SUCCESS);
400               ret = callbackObj->OnResult(ResultCode::SUCCESS, {});
401               if (ret != HDF_SUCCESS) {
402                   IAM_LOGE("callback result is %{public}d", ret);
403                   return HDF_FAILURE;
404               }
405               break;
406           case DriverCommandId::INIT_ALGORITHM:
407               IAM_LOGI("init algorithm, result is %{public}d", ResultCode::SUCCESS);
408               ret = callbackObj->OnResult(ResultCode::SUCCESS, {});
409               if (ret != HDF_SUCCESS) {
410                   IAM_LOGE("callback result is %{public}d", ret);
411                   return HDF_FAILURE;
412               }
413               break;
414           default:
415               IAM_LOGD("not support DriverCommandId : %{public}d", commandId);
416               ret = callbackObj->OnResult(ResultCode::OPERATION_NOT_SUPPORT, {});
417               if (ret != HDF_SUCCESS) {
418                   IAM_LOGE("callback result is %{public}d", ret);
419                   return HDF_FAILURE;
420               }
421       }
422       return HDF_SUCCESS;
423   }
424
425   // 实现获取执行器属性接口
426   int32_t AllInOneExecutorService::GetProperty(
427       const std::vector<uint64_t> &templateIdList, const std::vector<int32_t> &propertyTypes, Property &property)
428   {
429       IAM_LOGI("interface mock start");
430       property = {};
431       IAM_LOGI("get property success");
432       return HDF_SUCCESS;
433   }
434
435   // 实现设置需缓存模板列表接口
436   int32_t AllInOneExecutorService::SetCachedTemplates(const std::vector<uint64_t> &templateIdList)
437   {
438       IAM_LOGI("interface mock start");
439       IAM_LOGI("set cached templates success");
440       return HDF_SUCCESS;
441   }
442
443   // 实现注册SA命令回调接口
444   int32_t AllInOneExecutorService::RegisterSaCommandCallback(const sptr<ISaCommandCallback> &callbackObj)
445   {
446       IAM_LOGI("interface mock start");
447       IAM_LOGI("register sa command callback success");
448       return HDF_SUCCESS;
449   }
450   ```
451
4524. 用户身份认证框架支持多driver,当增加driver或者修改driver信息,需要修改如下文件中serviceName2Config。
453
454   ```c++
455   // base/user_iam/fingerprint_auth/services/src/fingerprint_auth_service.cpp
456   void FingerprintAuthService::StartDriverManager()
457   {
458       IAM_LOGI("start");
459       int32_t ret = UserAuth::IDriverManager::Start(HDI_NAME_2_CONFIG);
460       if (ret != UserAuth::ResultCode::SUCCESS) {
461           IAM_LOGE("start driver manager failed");
462       }
463   }
464   ```
465
466### 调测验证
467
468驱动开发完成后,开发者可以通过[用户认证API接口](../../application-dev/reference/apis-user-authentication-kit/js-apis-useriam-userauth.md)开发HAP应用,基于RK3568平台验证。认证和取消功能验证的测试代码如下:
469
4701.发起认证并获取认证结果的测试代码如下:
471
472```ts
473  // API version 10
474  import type {BusinessError} from '@ohos.base';
475  import userIAM_userAuth from '@ohos.userIAM.userAuth';
476
477  // 设置认证参数
478  const authParam: userIAM_userAuth.AuthParam = {
479    challenge: new Uint8Array([49, 49, 49, 49, 49, 49]),
480    authType: [userIAM_userAuth.UserAuthType.PIN, userIAM_userAuth.UserAuthType.FINGERPRINT],
481    authTrustLevel: userIAM_userAuth.AuthTrustLevel.ATL3,
482  };
483
484  // 配置认证界面
485  const widgetParam: userIAM_userAuth.WidgetParam = {
486    title: '请进行身份认证',
487  };
488
489  try {
490    // 获取认证对象
491    let userAuthInstance = userIAM_userAuth.getUserAuthInstance(authParam, widgetParam);
492    console.info('get userAuth instance success');
493    // 订阅认证结果
494    userAuthInstance.on('result', {
495      onResult(result) {
496        console.info(`userAuthInstance callback result: ${JSON.stringify(result)}`);
497        // 可在认证结束或其他业务需要场景,取消订阅认证结果
498        userAuthInstance.off('result');
499      }
500    });
501    console.info('auth on success');
502    userAuthInstance.start();
503    console.info('auth start success');
504  } catch (error) {
505    const err: BusinessError = error as BusinessError;
506    console.error(`auth catch error. Code is ${err?.code}, message is ${err?.message}`);
507  }
508```
509
5102.取消认证的测试代码如下:
511
512```ts
513  // API version 10
514  import type {BusinessError} from '@ohos.base';
515  import userIAM_userAuth from '@ohos.userIAM.userAuth';
516
517  const authParam: userIAM_userAuth.AuthParam = {
518    challenge: new Uint8Array([49, 49, 49, 49, 49, 49]),
519    authType: [userIAM_userAuth.UserAuthType.PIN, userIAM_userAuth.UserAuthType.FINGERPRINT],
520    authTrustLevel: userIAM_userAuth.AuthTrustLevel.ATL3,
521  };
522
523  const widgetParam: userIAM_userAuth.WidgetParam = {
524    title: '请进行身份认证',
525  };
526
527  try {
528    // 获取认证对象
529    let userAuthInstance = userIAM_userAuth.getUserAuthInstance(authParam, widgetParam);
530    console.info('get userAuth instance success');
531    // 开始认证
532    userAuthInstance.start();
533    console.info('auth start success');
534    // 取消认证
535    userAuthInstance.cancel();
536    console.info('auth cancel success');
537  } catch (error) {
538    const err: BusinessError = error as BusinessError;
539    console.error(`auth catch error. Code is ${err?.code}, message is ${err?.message}`);
540  }
541```