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 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 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```