1# Face_auth
2
3## 概述
4
5### 功能简介
6
7人脸识别功能是端侧设备不可或缺的一部分,为设备提供一种用户认证能力,可应用于设备解锁、支付、应用登录等身份认证场景。它是基于人的脸部特征信息进行身份识别的一种生物特征识别技术,用摄像机或摄像头采集含有人脸的图像或视频流,并自动在图像中检测和跟踪人脸,进而对检测到的人脸进行脸部识别,通常也叫做人像识别、面部识别、人脸认证。人脸识别功能整体框架如图1。
8
9基于HDF(Hardware Driver Foundation)驱动框架开发的Face_auth驱动,能够屏蔽硬件器件差异,为上层用户认证框架和Face_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上的应用包,本章节中仅代表Face_auth驱动的上层应用。
57
58- IDL接口
59
60  接口定义语言(Interface Definition Language)通过IDL编译器编译后,能够生成与编程语言相关的文件:客户端桩文件,服务器框架文件。本文主要是通过IDL接口生成的客户端和服务端来实现Face_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
72Face_auth驱动的主要工作是为上层用户认证框架和Face_auth服务提供稳定的人脸识别基础能力,保证设备上人脸识别功能可以正常运行。
73开发者可基于HDF框架对不同芯片进行各自驱动的开发及HDI层接口的调用。
74
75**图2** Face_auth服务和Face_auth驱动交互
76
77![image](figures/人脸识别服务和faceauth驱动接口.png "人脸识别服务和faceauth驱动接口")
78
79### 约束与限制
80
81- 要求设备上具备摄像器件,且人脸图像像素大于100*100。
82- 要求设备上具有可信执行环境,人脸特征信息高强度加密保存在可信执行环境中。
83- 对于面部特征相似的人、面部特征不断发育的儿童,人脸特征匹配率有所不同。如果对此担忧,可考虑其他认证方式。
84
85## 开发指导
86
87### 场景介绍
88
89Face_auth驱动的主要工作是为上层用户认证框架和Face_auth服务提供稳定的人脸识别基础能力,保证设备上人脸识别功能可以正常运行。
90
91### 接口说明
92
93注:以下接口列举的为IDL接口描述生成的对应C++语言函数接口,接口声明见idl文件(/drivers/interface/face_auth)。
94
95在本文中,人脸凭据的录入、认证、识别和删除相关的HDI接口如表1所示,表2中的回调函数分别用于人脸执行器返回操作结果给框架和返回操作过程中的提示信息给上层应用。
96
97**表1** 接口功能介绍
98
99| 接口名称       | 功能介绍         |
100| ----------------------------------- | ---------------------------------- |
101| GetExecutorList(std::vector\<sptr\<IAllInOneExecutor>>& allInOneExecutors) | 获取V2_0版本执行器列表。 |
102| GetExecutorInfo(ExecutorInfo& info)      | 获取执行器信息,包括执行器类型、执行器角色、认证类型、安全等级、执行器公钥等信息,用于向用户认证框架注册执行器。 |
103| OnRegisterFinish(const std::vector\<uint64_t>& templateIdList,<br/>        const std::vector\<uint8_t>& frameworkPublicKey, const std::vector\<uint8_t>& extraInfo) | 执行器注册成功后,获取用户认证框架的公钥信息;获取用户认证框架的人脸模板列表用于对账。 |
104| Enroll(uint64_t scheduleId, const std::vector\<uint8_t>& extraInfo,<br/>        const sptr\<IExecutorCallback>& callbackObj) | 录入人脸模板。             |
105| Authenticate(uint64_t scheduleId, const std::vector\<uint64_t>& templateIdList,<br/>        const std::vector\<uint8_t>& extraInfo, const sptr\<IExecutorCallback>& callbackObj) | 认证人脸模板。         |
106| Identify(uint64_t scheduleId, const std::vector\<uint8_t>& extraInfo,<br/>        const sptr\<IExecutorCallback>& callbackObj) | 识别人脸模板。                                               |
107| Delete(const std::vector\<uint64_t>& templateIdList)          | 删除人脸模板。  |
108| Cancel(uint64_t scheduleId)                                  | 通过scheduleId取消指定录入、认证、识别操作。  |
109| SendCommand(int32_t commandId, const std::vector\<uint8_t>& extraInfo,<br/>        const sptr\<IExecutorCallback>& callbackObj) | 人脸认证服务向Face_auth驱动传递参数的通用接口。              |
110| SetBufferProducer(const sptr\<BufferProducerSequenceable> &bufferProducer) | 设置预览流缓冲区。 |
111| GetProperty(const std::vector\<uint64_t>& templateIdList,<br/>const std::vector\<int32_t>& propertyTypes, Property& property) | 获取执行器属性信息。 |
112| SetCachedTemplates(const std::vector\<uint64_t> &templateIdList) | 设置需缓存模板列表。 |
113| RegisterSaCommandCallback(const sptr\<ISaCommandCallback> &callbackObj) | 注册SA命令回调。 |
114
115**表2** 回调函数介绍
116
117| 接口名称                                                       | 功能介绍                 |
118| ------------------------------------------------------------ | ------------------------ |
119| ExecutorCallbackService::OnResult(int32_t result, const std::vector\<uint8_t>& extraInfo) | 返回操作的最终结果。     |
120| ExecutorCallbackService::OnTip(int32_t tip, const std::vector\<uint8_t>& extraInfo) | 返回操作的过程交互信息。 |
121| SaCommandCallbackService::OnSaCommands(const std::vector\<SaCommand>& commands) | 发送命令列表。 |
122
123### 开发步骤
124
125以Hi3516DV300平台为例,我们提供了Face_auth驱动DEMO实例,以下是目录结构及各部分功能简介。
126
127```undefined
128// drivers/peripheral/face_auth
129├── BUILD.gn     # 编译脚本
130├── bundle.json  # 组件描述文件
131└── hdi_service  # Face_auth驱动实现
132    ├── BUILD.gn    # 编译脚本
133    ├── include     # 头文件
134    └── src         # 源文件
135        ├── executor_impl.cpp                # 认证、录入等功能接口实现
136        ├── face_auth_interface_driver.cpp   # Face_auth驱动入口
137        └── face_auth_interface_service.cpp  # 获取执行器列表接口实现
138```
139
140下面结合DEMO实例介绍驱动开发的具体步骤。
141
1421. 基于HDF驱动框架,按照驱动Driver Entry程序,完成Face_auth驱动开发,主要由Bind、Init、Release、Dispatch函数接口实现,详细代码参见[face_auth_interface_driver.cpp](https://gitee.com/openharmony/drivers_peripheral/blob/master/face_auth/hdi_service/src/face_auth_interface_driver.cpp)文件。
143
144   ```c++
145   // 通过自定义的HdfFaceAuthInterfaceHost对象包含ioService对象和真正的HDI Service实现IRemoteObject对象
146   struct HdfFaceAuthInterfaceHost {
147       struct IDeviceIoService ioService;
148       OHOS::sptr<OHOS::IRemoteObject> stub;
149   };
150
151   // 服务接口调用响应接口
152   int32_t FaceAuthInterfaceDriverDispatch(
153       struct HdfDeviceIoClient *client, int cmdId, struct HdfSBuf *data, struct HdfSBuf *reply)
154   {
155       IAM_LOGI("start");
156       if (client == nullptr || data == nullptr || reply == nullptr || client->device == nullptr ||
157           client->device->service == nullptr) {
158           IAM_LOGE("invalid param");
159           return HDF_ERR_INVALID_PARAM;
160       }
161
162       auto *hdfFaceAuthInterfaceHost = CONTAINER_OF(client->device->service, struct HdfFaceAuthInterfaceHost, ioService);
163       if (hdfFaceAuthInterfaceHost == nullptr || hdfFaceAuthInterfaceHost->stub == nullptr) {
164           IAM_LOGE("hdfFaceAuthInterfaceHost is invalid");
165           return HDF_ERR_INVALID_PARAM;
166       }
167
168       OHOS::MessageParcel *dataParcel = nullptr;
169       OHOS::MessageParcel *replyParcel = nullptr;
170       OHOS::MessageOption option;
171
172       if (SbufToParcel(data, &dataParcel) != HDF_SUCCESS) {
173           IAM_LOGE("invalid data sbuf object to dispatch");
174           return HDF_ERR_INVALID_PARAM;
175       }
176       if (SbufToParcel(reply, &replyParcel) != HDF_SUCCESS) {
177           IAM_LOGE("invalid reply sbuf object to dispatch");
178           return HDF_ERR_INVALID_PARAM;
179       }
180
181       return hdfFaceAuthInterfaceHost->stub->SendRequest(cmdId, *dataParcel, *replyParcel, option);
182   }
183
184   // 初始化接口
185   int HdfFaceAuthInterfaceDriverInit(struct HdfDeviceObject *deviceObject)
186   {
187       IAM_LOGI("start");
188       if (deviceObject == nullptr) {
189           IAM_LOGE("deviceObject is nullptr");
190           return HDF_ERR_INVALID_PARAM;
191       }
192       if (!HdfDeviceSetClass(deviceObject, DEVICE_CLASS_USERAUTH)) {
193           IAM_LOGE("set face auth hdf class failed");
194           return HDF_FAILURE;
195       }
196       return HDF_SUCCESS;
197   }
198
199   // Face_auth驱动对外提供的服务绑定到HDF框架
200   int HdfFaceAuthInterfaceDriverBind(struct HdfDeviceObject *deviceObject)
201   {
202       IAM_LOGI("start");
203       if (deviceObject == nullptr) {
204           IAM_LOGE("deviceObject is nullptr");
205           return HDF_ERR_INVALID_PARAM;
206       }
207       auto *hdfFaceAuthInterfaceHost = new (std::nothrow) HdfFaceAuthInterfaceHost;
208       if (hdfFaceAuthInterfaceHost == nullptr) {
209           IAM_LOGE("failed to create HdfFaceAuthInterfaceHost object");
210           return HDF_FAILURE;
211       }
212
213       hdfFaceAuthInterfaceHost->ioService.Dispatch = FaceAuthInterfaceDriverDispatch;
214       hdfFaceAuthInterfaceHost->ioService.Open = NULL;
215       hdfFaceAuthInterfaceHost->ioService.Release = NULL;
216
217       auto serviceImpl = IFaceAuthInterface::Get(true);
218       if (serviceImpl == nullptr) {
219           IAM_LOGE("failed to get of implement service");
220           delete hdfFaceAuthInterfaceHost;
221           return HDF_FAILURE;
222       }
223
224       hdfFaceAuthInterfaceHost->stub =
225           OHOS::HDI::ObjectCollector::GetInstance().GetOrNewObject(serviceImpl, IFaceAuthInterface::GetDescriptor());
226       if (hdfFaceAuthInterfaceHost->stub == nullptr) {
227           IAM_LOGE("failed to get stub object");
228           delete hdfFaceAuthInterfaceHost;
229           return HDF_FAILURE;
230       }
231
232       deviceObject->service = &hdfFaceAuthInterfaceHost->ioService;
233       IAM_LOGI("success");
234       return HDF_SUCCESS;
235   }
236
237   // 释放Face_auth驱动中的资源
238   void HdfFaceAuthInterfaceDriverRelease(struct HdfDeviceObject *deviceObject)
239   {
240       IAM_LOGI("start");
241       if (deviceObject == nullptr || deviceObject->service == nullptr) {
242           IAM_LOGE("deviceObject is invalid");
243           return;
244       }
245       auto *hdfFaceAuthInterfaceHost = CONTAINER_OF(deviceObject->service, struct HdfFaceAuthInterfaceHost, ioService);
246       if (hdfFaceAuthInterfaceHost == nullptr) {
247           IAM_LOGE("hdfFaceAuthInterfaceHost is nullptr");
248           return;
249       }
250       delete hdfFaceAuthInterfaceHost;
251       IAM_LOGI("success");
252   }
253
254   // 注册Face_auth驱动入口数据结构体对象
255   struct HdfDriverEntry g_faceAuthInterfaceDriverEntry = {
256       .moduleVersion = 1,
257       .moduleName = "drivers_peripheral_face_auth",
258       .Bind = HdfFaceAuthInterfaceDriverBind,
259       .Init = HdfFaceAuthInterfaceDriverInit,
260       .Release = HdfFaceAuthInterfaceDriverRelease,
261   };
262
263   // 调用HDF_INIT将驱动入口注册到HDF框架中。在加载驱动时HDF框架会先调用Bind函数,再调用Init函数加载该驱动。当Init调用异常时,HDF框架会调用Release释放驱动资源并退出
264   HDF_INIT(g_faceAuthInterfaceDriverEntry);
265   ```
266
2672. 实现获取执行器列表接口,详细代码参见[face_auth_interface_service.cpp](https://gitee.com/openharmony/drivers_peripheral/blob/master/face_auth/hdi_service/src/face_auth_interface_service.cpp)文件。
268
269   ```c++
270   // 执行器实现类
271   class AllInOneExecutorImpl : public IAllInOneExecutor {
272   public:
273       AllInOneExecutorImpl(struct ExecutorInfo executorInfo);
274       virtual ~AllInOneExecutorImpl() {}
275
276   private:
277       struct ExecutorInfo executorInfo_; // 执行器信息
278   };
279
280   static constexpr uint16_t SENSOR_ID = 123; // 执行器sensorID
281   static constexpr uint32_t EXECUTOR_TYPE = 123; // 执行器类型
282   static constexpr size_t PUBLIC_KEY_LEN = 32; // 执行器32字节公钥
283
284   // 创建HDI服务对象
285   extern "C" IFaceAuthInterface *FaceAuthInterfaceImplGetInstance(void)
286   {
287       auto faceAuthInterfaceService = new (std::nothrow) FaceAuthInterfaceService();
288       if (faceAuthInterfaceService == nullptr) {
289           IAM_LOGE("faceAuthInterfaceService is nullptr");
290           return nullptr;
291       }
292       return faceAuthInterfaceService;
293   }
294
295   // 获取V2_0执行器列表实现
296   int32_t GetExecutorList(std::vector<sptr<IAllInOneExecutor>> &executorList)
297   {
298       IAM_LOGI("interface mock start");
299       for (auto executor : executorList_) {
300           executorList.push_back(executor);
301       }
302       IAM_LOGI("interface mock success");
303       return HDF_SUCCESS;
304   }
305   ```
306
3073. 实现执行器每个功能接口,详细代码参见[all_in_one_executor_impl.cpp](https://gitee.com/openharmony/drivers_peripheral/blob/master/face_auth/hdi_service/src/all_in_one_executor_impl.cpp)文件。
308
309   ```c++
310   // 实现获取执行器信息接口
311   int32_t AllInOneExecutorImpl::GetExecutorInfo(ExecutorInfo &executorInfo)
312   {
313       IAM_LOGI("interface mock start");
314       executorInfo = executorInfo_;
315       IAM_LOGI("get executor information success");
316       return HDF_SUCCESS;
317   }
318
319   // 实现执行器注册成功后,获取用户认证框架的公钥信息、获取用户认证框架的模板列表接口。将公钥信息保持,模板列表用于和本地的模板做对账
320   int32_t AllInOneExecutorImpl::OnRegisterFinish(const std::vector<uint64_t> &templateIdList,
321       const std::vector<uint8_t> &frameworkPublicKey, const std::vector<uint8_t> &extraInfo)
322   {
323       IAM_LOGI("interface mock start");
324       static_cast<void>(templateIdList);
325       static_cast<void>(extraInfo);
326       static_cast<void>(frameworkPublicKey);
327       IAM_LOGI("register finish");
328       return HDF_SUCCESS;
329   }
330
331   // 实现人脸录入接口
332   int32_t AllInOneExecutorImpl::Enroll(
333       uint64_t scheduleId, const std::vector<uint8_t> &extraInfo, const sptr<IExecutorCallback> &callbackObj)
334   {
335       IAM_LOGI("interface mock start");
336       static_cast<void>(scheduleId);
337       static_cast<void>(extraInfo);
338       if (callbackObj == nullptr) {
339           IAM_LOGE("callbackObj is nullptr");
340           return HDF_ERR_INVALID_PARAM;
341       }
342       IAM_LOGI("enroll, result is %{public}d", ResultCode::OPERATION_NOT_SUPPORT);
343       int32_t ret = callbackObj->OnResult(ResultCode::OPERATION_NOT_SUPPORT, {});
344       if (ret != HDF_SUCCESS) {
345           IAM_LOGE("callback result is %{public}d", ret);
346           return HDF_FAILURE;
347       }
348       return HDF_SUCCESS;
349   }
350
351   // 实现人脸认证接口
352   int32_t AllInOneExecutorImpl::Authenticate(uint64_t scheduleId, const std::vector<uint64_t> &templateIdList,
353       const std::vector<uint8_t> &extraInfo, const sptr<IExecutorCallback> &callbackObj)
354   {
355       IAM_LOGI("interface mock start");
356       static_cast<void>(scheduleId);
357       static_cast<void>(templateIdList);
358       static_cast<void>(extraInfo);
359       if (callbackObj == nullptr) {
360           IAM_LOGE("callbackObj is nullptr");
361           return HDF_ERR_INVALID_PARAM;
362       }
363       IAM_LOGI("authenticate, result is %{public}d", ResultCode::NOT_ENROLLED);
364       int32_t ret = callbackObj->OnResult(ResultCode::NOT_ENROLLED, {});
365       if (ret != HDF_SUCCESS) {
366           IAM_LOGE("callback result is %{public}d", ret);
367           return HDF_FAILURE;
368       }
369       return HDF_SUCCESS;
370   }
371
372   // 实现人脸识别接口
373   int32_t AllInOneExecutorImpl::Identify(
374       uint64_t scheduleId, const std::vector<uint8_t> &extraInfo, const sptr<IExecutorCallback> &callbackObj)
375   {
376       IAM_LOGI("interface mock start");
377       static_cast<void>(scheduleId);
378       static_cast<void>(extraInfo);
379       if (callbackObj == nullptr) {
380           IAM_LOGE("callbackObj is nullptr");
381           return HDF_ERR_INVALID_PARAM;
382       }
383       IAM_LOGI("identify, result is %{public}d", ResultCode::OPERATION_NOT_SUPPORT);
384       int32_t ret = callbackObj->OnResult(ResultCode::OPERATION_NOT_SUPPORT, {});
385       if (ret != HDF_SUCCESS) {
386           IAM_LOGE("callback result is %{public}d", ret);
387           return HDF_FAILURE;
388       }
389       return HDF_SUCCESS;
390   }
391
392   // 实现删除人脸模板接口
393   int32_t AllInOneExecutorImpl::Delete(const std::vector<uint64_t> &templateIdList)
394   {
395       IAM_LOGI("interface mock start");
396       static_cast<void>(templateIdList);
397       IAM_LOGI("delete success");
398       return HDF_SUCCESS;
399   }
400
401   // 实现通过scheduleId取消指定操作接口
402   int32_t AllInOneExecutorImpl::Cancel(uint64_t scheduleId)
403   {
404       IAM_LOGI("interface mock start");
405       static_cast<void>(scheduleId);
406       IAM_LOGI("cancel success");
407       return HDF_SUCCESS;
408   }
409
410   // 实现人脸认证服务向Face_auth驱动传递参数的通用接口,当前需要实现冻结与解锁模板命令
411   int32_t AllInOneExecutorImpl::SendCommand(
412       int32_t commandId, const std::vector<uint8_t> &extraInfo, const sptr<IExecutorCallback> &callbackObj)
413   {
414       IAM_LOGI("interface mock start");
415       static_cast<void>(extraInfo);
416       if (callbackObj == nullptr) {
417           IAM_LOGE("callbackObj is nullptr");
418           return HDF_ERR_INVALID_PARAM;
419       }
420       int32_t ret;
421       switch (commandId) {
422           case DriverCommandId::LOCK_TEMPLATE:
423               IAM_LOGI("lock template, result is %{public}d", ResultCode::SUCCESS);
424               ret = callbackObj->OnResult(ResultCode::SUCCESS, {});
425               if (ret != HDF_SUCCESS) {
426                   IAM_LOGE("callback result is %{public}d", ret);
427                   return HDF_FAILURE;
428               }
429               break;
430           case DriverCommandId::UNLOCK_TEMPLATE:
431               IAM_LOGI("unlock template, result is %{public}d", ResultCode::SUCCESS);
432               ret = callbackObj->OnResult(ResultCode::SUCCESS, {});
433               if (ret != HDF_SUCCESS) {
434                   IAM_LOGE("callback result is %{public}d", ret);
435                   return HDF_FAILURE;
436               }
437               break;
438           case DriverCommandId::INIT_ALGORITHM:
439               IAM_LOGI("init algorithm, result is %{public}d", ResultCode::SUCCESS);
440               ret = callbackObj->OnResult(ResultCode::SUCCESS, {});
441               if (ret != HDF_SUCCESS) {
442                   IAM_LOGE("callback result is %{public}d", ret);
443                   return HDF_FAILURE;
444               }
445               break;
446           default:
447               IAM_LOGD("not support DriverCommandId : %{public}d", commandId);
448               ret = callbackObj->OnResult(ResultCode::OPERATION_NOT_SUPPORT, {});
449               if (ret != HDF_SUCCESS) {
450                   IAM_LOGE("callback result is %{public}d", ret);
451                   return HDF_FAILURE;
452               }
453       }
454       return HDF_SUCCESS;
455   }
456
457   // 实现设置预览流缓冲区接口
458   int32_t FaceAuthInterfaceService::SetBufferProducer(const sptr<BufferProducerSequenceable> &bufferProducer)
459   {
460       IAM_LOGI("interface mock start set buffer producer %{public}s",
461           UserIam::Common::GetPointerNullStateString(bufferProducer.GetRefPtr()).c_str());
462       return HDF_SUCCESS;
463   }
464
465   // 实现获取执行器属性接口
466   int32_t AllInOneExecutorImpl::GetProperty(
467       const std::vector<uint64_t> &templateIdList, const std::vector<int32_t> &propertyTypes, Property &property)
468   {
469       IAM_LOGI("interface mock start");
470       property = {};
471       IAM_LOGI("get property success");
472       return HDF_SUCCESS;
473   }
474
475   // 实现设置需缓存模板列表接口
476   int32_t AllInOneExecutorImpl::SetCachedTemplates(const std::vector<uint64_t> &templateIdList)
477   {
478       IAM_LOGI("interface mock start");
479       IAM_LOGI("set cached templates success");
480       return HDF_SUCCESS;
481   }
482
483   // 实现注册SA命令回调接口
484   int32_t AllInOneExecutorImpl::RegisterSaCommandCallback(const sptr<ISaCommandCallback> &callbackObj)
485   {
486       IAM_LOGI("interface mock start");
487       IAM_LOGI("register sa command callback success");
488       return HDF_SUCCESS;
489   }
490   ```
491
4924. 用户身份认证框架支持多driver,当增加driver或者修改driver信息,需要修改如下文件中serviceName2Config。
493
494   ```c++
495   // base/user_iam/face_auth/services/src/face_auth_service.cpp
496   void FaceAuthService::StartDriverManager()
497   {
498       IAM_LOGI("start");
499       int32_t ret = UserAuth::IDriverManager::Start(HDI_NAME_2_CONFIG);
500       if (ret != FACE_AUTH_SUCCESS) {
501           IAM_LOGE("start driver manager failed");
502       }
503   }
504   ```
505
506### 调测验证
507
508驱动开发完成后,通过[用户认证API接口](../../application-dev/reference/apis-user-authentication-kit/js-apis-useriam-userauth.md)开发HAP应用,基于RK3568平台验证。认证和取消功能验证的测试代码如下:
509
5101.发起认证并获取认证结果的测试代码如下:
511
512```ts
513  // API version 10
514  import type {BusinessError} from '@ohos.base';
515  import userIAM_userAuth from '@ohos.userIAM.userAuth';
516
517  // 设置认证参数
518  const authParam: userIAM_userAuth.AuthParam = {
519    challenge: new Uint8Array([49, 49, 49, 49, 49, 49]),
520    authType: [userIAM_userAuth.UserAuthType.PIN, userIAM_userAuth.UserAuthType.FACE],
521    authTrustLevel: userIAM_userAuth.AuthTrustLevel.ATL3,
522  };
523
524  // 配置认证界面
525  const widgetParam: userIAM_userAuth.WidgetParam = {
526    title: '请进行身份认证',
527  };
528
529  try {
530    // 获取认证对象
531    let userAuthInstance = userIAM_userAuth.getUserAuthInstance(authParam, widgetParam);
532    console.info('get userAuth instance success');
533    // 订阅认证结果
534    userAuthInstance.on('result', {
535      onResult(result) {
536        console.info(`userAuthInstance callback result: ${JSON.stringify(result)}`);
537        // 可在认证结束或其他业务需要场景,取消订阅认证结果
538        userAuthInstance.off('result');
539      }
540    });
541    console.info('auth on success');
542    userAuthInstance.start();
543    console.info('auth start success');
544  } catch (error) {
545    const err: BusinessError = error as BusinessError;
546    console.error(`auth catch error. Code is ${err?.code}, message is ${err?.message}`);
547  }
548```
549
5502.取消认证的测试代码如下:
551```ts
552  // API version 10
553  import type {BusinessError} from '@ohos.base';
554  import userIAM_userAuth from '@ohos.userIAM.userAuth';
555
556  const authParam: userIAM_userAuth.AuthParam = {
557    challenge: new Uint8Array([49, 49, 49, 49, 49, 49]),
558    authType: [userIAM_userAuth.UserAuthType.PIN, userIAM_userAuth.UserAuthType.FACE],
559    authTrustLevel: userIAM_userAuth.AuthTrustLevel.ATL3,
560  };
561
562  const widgetParam: userIAM_userAuth.WidgetParam = {
563    title: '请进行身份认证',
564  };
565
566  try {
567    // 获取认证对象
568    let userAuthInstance = userIAM_userAuth.getUserAuthInstance(authParam, widgetParam);
569    console.info('get userAuth instance success');
570    // 开始认证
571    userAuthInstance.start();
572    console.info('auth start success');
573    // 取消认证
574    userAuthInstance.cancel();
575    console.info('auth cancel success');
576  } catch (error) {
577    const err: BusinessError = error as BusinessError;
578    console.error(`auth catch error. Code is ${err?.code}, message is ${err?.message}`);
579  }
580```