001/* 002 * =========================================================================================== 003 * = COPYRIGHT 004 * PAX Computer Technology (Shenzhen) Co., Ltd. PROPRIETARY INFORMATION 005 * This software is supplied under the terms of a license agreement or nondisclosure 006 * agreement with PAX Computer Technology (Shenzhen) Co., Ltd. and may not be copied or 007 * disclosed except in accordance with the terms in that agreement. 008 * Copyright (C) 2017-2023 PAX Computer Technology (Shenzhen) Co., Ltd. All rights reserved. 009 * Description: // Detail description about the function of this module, 010 * // interfaces with the other modules, and dependencies. 011 * Revision History: 012 * Date Author Action 013 * 2017/04/01 PAX Create/Add/Modify/Delete 014 * =========================================================================================== 015 */ 016package com.pax.dal; 017 018import android.os.Bundle; 019 020import com.pax.dal.entity.LivenessDetectResult; 021import com.pax.dal.exceptions.LivenessDetectException; 022 023import java.util.List; 024 025/** 026 * <div class="zh">活体检测。</div> <div class="en">The Liveness Detector.</div> 027 * 028 * @since V3.19.00 029 */ 030public interface ILivenessDetector { 031 032 /** 033 * <div class="zh">获取活体检测配置信息。</div> <div class="en">Get the liveness detection configuration information.</div> 034 * 035 * @return <div class="zh"> 036 * <table border="1"> 037 * <tr> 038 * <th>Key</th> 039 * <th>类型</th> 040 * <th>说明</th> 041 * </tr> 042 * <tr> 043 * <td>algorithmflag</td> 044 * <td>int</td> 045 * <td>算法厂商标识码。 01:云从;02:奥比中光;03:华捷;04:百富。</td> 046 * </tr> 047 * <tr> 048 * <td>algorithmver</td> 049 * <td>String</td> 050 * <td>算法版本。</td> 051 * </tr> 052 * <tr> 053 * <td>mode</td> 054 * <td>int</td> 055 * <td>活检方式。01:3D;02:红外双目;03:TOF。</td> 056 * </tr> 057 * <tr> 058 * <td>camerainfo</td> 059 * <td>String</td> 060 * <td>摄像头信息。</td> 061 * </tr> 062 * <tr> 063 * <td>cameramanu</td> 064 * <td>String</td> 065 * <td>摄像头厂商。</td> 066 * </tr> 067 * <tr> 068 * <td>cameramodel</td> 069 * <td>String</td> 070 * <td>型号。</td> 071 * </tr> 072 * <tr> 073 * <td>previewArea</td> 074 * <td>android.graphics.Rect</td> 075 * <td>获取预览坐标,主要用于自定义faceUI时计算坐标位置。</td> 076 * </tr> 077 * <tr> 078 * <td>cameraSize</td> 079 * <td>android.graphics.Rect</td> 080 * <td>获取相机大小。</td> 081 * </tr> 082 * </table> 083 * </div> 084 * <div class="en"> 085 * <table border="1"> 086 * <tr> 087 * <th>Key</th> 088 * <th>Type</th> 089 * <th>Instructions</th> 090 * </tr> 091 * <tr> 092 * <td>algorithmflag</td> 093 * <td>int</td> 094 * <td>Algorithm vendor identification code. 01:CloudWork;02:Orbbec;03:HuaJie;04:PAX.</td> 095 * </tr> 096 * <tr> 097 * <td>algorithmver</td> 098 * <td>String</td> 099 * <td>Algorithm version.</td> 100 * </tr> 101 * <tr> 102 * <td>mode</td> 103 * <td>int</td> 104 * <td>Detect way.01:3D;02:Infrared binocular;03:TOF.</td> 105 * </tr> 106 * <tr> 107 * <td>camerainfo</td> 108 * <td>String</td> 109 * <td>Camera information.</td> 110 * </tr> 111 * <tr> 112 * <td>cameramanu</td> 113 * <td>String</td> 114 * <td>Camera manufacturer.</td> 115 * </tr> 116 * <tr> 117 * <td>cameramodel</td> 118 * <td>String</td> 119 * <td>Camera model.</td> 120 * </tr> 121 * <tr> 122 * <td>previewArea</td> 123 * <td>android.graphics.Rect</td> 124 * <td>Get the preview coordinates, mainly used to calculate the coordinate position when customizing the faceUI.</td> 125 * </tr> 126 * <tr> 127 * <td>cameraSize</td> 128 * <td>android.graphics.Rect</td> 129 * <td>Get the camera size.</td> 130 * </tr> 131 * </table> 132 * </div> 133 * 134 * @throws LivenessDetectException 135 * @since V3.19.00 136 */ 137 Bundle getConfig() throws LivenessDetectException; 138 139 /** 140 * <div class="zh">初始化活检相机。</div> <div class="en">Initialize the liveness detection camera.</div> 141 * 142 * @throws LivenessDetectException 143 * @since V3.19.00 144 */ 145 void init() throws LivenessDetectException; 146 147 /** 148 * <div class="zh">进行活体检测。</div> <div class="en">Start liveness detect.</div> 149 * 150 * @param param <div class="zh">活体检测配置。 151 * <table border="1"> 152 * <tr> 153 * <th>Key</th> 154 * <th>类型</th> 155 * <th>说明</th> 156 * </tr> 157 * <tr> 158 * <td>timeout</td> 159 * <td>int</td> 160 * <td>超时时间,毫秒。默认60000ms,最小15000ms。</td> 161 * </tr> 162 * <tr> 163 * <td>matchscore</td> 164 * <td>double</td> 165 * <td>评分阀值,0.0-1.0。默认0.5。</td> 166 * </tr> 167 * <tr> 168 * <td>picnumber</td> 169 * <td>int</td> 170 * <td>活检输出图片数量,默认1。</td> 171 * </tr> 172 * <tr> 173 * <td>timeinterval</td> 174 * <td>int</td> 175 * <td>毫秒,最低采样时间间隔,默认200毫秒。</td> 176 * </tr> 177 * <tr> 178 * <td>amount</td> 179 * <td>String</td> 180 * <td>消费金额,支持Html格式设置颜色,如"<xmp><font color='#ff0000'>240.5</font></xmp>"。</td> 181 * </tr> 182 * <tr> 183 * <td>detectArea</td> 184 * <td>android.graphics.Rect</td> 185 * <td>检测区域坐标,使用自定义UI界面时需设置。</td> 186 * </tr> 187 * <tr> 188 * <td>shouldPlayVoice</td> 189 * <td>boolean</td> 190 * <td>true:播放语言提示;false:不播放语言提示。默认播放。</td> 191 * </tr> 192 * <tr> 193 * <td>checkQuality</td> 194 * <td>boolean</td> 195 * <td>true:进行质量检测;false:不质量检测。默认不开启质量检测。<br>如果开启会有以下提示: <br>1.离得太远: 请往前移一点 <br> 196 * 2.人脸有角度或者闭眼(大于30度): 请保持脸部端正 <br>3.脸部有遮挡 <br>4.请摘下口罩<br>5.请摘下墨镜<br>6.多人脸<br> 7.活体检测失败 197 * <font color=red>已废弃。如需使用,请在{@link #init(Bundle)}使用。</font> 198 * </td> 199 * </tr> 200 * <tr> 201 * <td>enableMultipleFaces</td> 202 * <td>boolean</td> 203 * <td>true:存在多人脸时,允许活检通过;false:存在多人脸时,不允许活检通过。默认true。</td> 204 * </tr> 205 * <tr> 206 * <td>showFaceRect</td> 207 * <td>boolean</td> 208 * <td>true:绘制人脸框;false:不绘制人脸框。默认false。</td> 209 * </tr> 210 * </table> 211 * </div> 212 * <div class="en">Liveness detection configuration. 213 * <table border="1"> 214 * <tr> 215 * <th>Key</th> 216 * <th>Type</th> 217 * <th>Instructions</th> 218 * </tr> 219 * <tr> 220 * <td>timeout</td> 221 * <td>int</td> 222 * <td>Timeout in milliseconds.Default is 60000ms, minimum 15000ms.</td> 223 * </tr> 224 * <tr> 225 * <td>matchscore</td> 226 * <td>double</td> 227 * <td>Scoring threshold, 0.0-1.0.The default is 0.5.</td> 228 * </tr> 229 * <tr> 230 * <td>picnumber</td> 231 * <td>int</td> 232 * <td>The number of detection output images, default 1.</td> 233 * </tr> 234 * <tr> 235 * <td>timeinterval</td> 236 * <td>int</td> 237 * <td>Ms, minimum sampling interval, default 200 ms.</td> 238 * </tr> 239 * <tr> 240 * <td>amount</td> 241 * <td>String</td> 242 * <td>Amount spent. Supports HTML formatting for font colors such as "<xmp><font color='#ff0000'>240.5</font></xmp>".</td> 243 * </tr> 244 * <tr> 245 * <td>detectArea</td> 246 * <td>android.graphics.Rect</td> 247 * <td>Detect area coordinates. it is required to set when using the custom UI interface.</td> 248 * </tr> 249 * <tr> 250 * <td>shouldPlayVoice</td> 251 * <td>boolean</td> 252 * <td>True: Play language prompt;False: Language prompts are not played.Play by default.</td> 253 * </tr> 254 * <tr> 255 * <td>checkQuality</td> 256 * <td>boolean</td> 257 * <td>True: check the quality; false: do not check the quality. Quality check is not performed by default.<br> 258 * If check the quality, the following prompts will appear:<br>1.It's too far: please move forward a little <br> 259 * 2.Face with Angle or closed eyes (> 30 degrees): Keep face straight<br>3.The face is covered<br> 260 * 4.Please take off the mask<br>5.Please take off the sunglasses<br> 6.Multiple faces<br>7.Detection failed 261 * <font color=red>Obsolete. If you need to use it, please use it in {@link #init(Bundle)}.</font> 262 * </td> 263 * </tr> 264 * <tr> 265 * <td>enableMultipleFaces</td> 266 * <td>boolean</td> 267 * <td>True: Detection is allowed in the presence of multiple faces;False: Detection is not allowed in the presence of multiple faces.True by default.</td> 268 * </tr> 269 * <tr> 270 * <td>showFaceRect</td> 271 * <td>boolean</td> 272 * <td>True: Draw a real-time face rectangle.;False: Not draw a real-time face rectangle.False by default.</td> 273 * </tr> 274 * </table> 275 * </div> 276 * 277 * @param listener {@link LivenessDetectListener} 278 * @throws LivenessDetectException 279 * @since V3.19.00 280 */ 281 void detect(Bundle param, LivenessDetectListener listener) throws LivenessDetectException; 282 283 /** 284 * <div class="zh">停止活体检测。 285 * 1.有界面活检时,该接口用于中断{@link #detect(Bundle, LivenessDetectListener)},如果{@link #detect(Bundle, LivenessDetectListener)}已结束则无需调用该接口。 286 * 2.客户自定义活检界面时,如果未调用{@link #detectLite(LivenessDetectListener)},只是调用{@link #setFaceUICallBack(IFaceUIManager)}进行预览,可用该接口停止预览。 287 * 如果{@link #setFaceUICallBack(IFaceUIManager)}和{@link #detectLite(LivenessDetectListener)}都调用了,可用该接口停止预览和活检。 288 * </div> 289 * <div class="en">Stop liveness detect. 290 * 1.When there is an interface biopsy, this interface is used to interrupt {@link #detect(Bundle, LivenessDetectListener)}, if {@link #detect(Bundle, LivenessDetectListener)} has ended, there is no need to call this interface. 291 * 2.When the customer customizes the biopsy interface, if {@link #detectLite(LivenessDetectListener)} is not called, but {@link #setFaceUICallBack(IFaceUIManager)} is only called to preview, this interface can be used to stop the preview. 292 * If both {@link #setFaceUICallBack(IFaceUIManager)} and {@link #detectLite(LivenessDetectListener)} are called, this interface can be used to stop the preview and biopsy. 293 * </div> 294 * 295 * @throws LivenessDetectException 296 * @since V3.19.00 297 */ 298 void stop() throws LivenessDetectException; 299 300 /** 301 * <div class="zh">释放活检相机。如果不调用该接口,其它应用会无法直接使用活检相机。 302 * 如果不存在直接调用活检相机的应用,可不调用此接口,这样可快速开启活检相机进行预览。</div> 303 * <div class="en">Release the liveness detection camera. Without this interface, other applications will not be able to use the liveness detection camera directly. 304 * If there is no application that calls the liveness detection camera directly, this interface may not be called, so that the liveness detection camera can be quickly turned on for preview.</div> 305 * 306 * @throws LivenessDetectException 307 * @since V3.19.00 308 */ 309 void release() throws LivenessDetectException; 310 311 /** 312 * <div class="zh">使用自定义UI界面。接口在{@link #detect(Bundle, LivenessDetectListener)}前调用。</div> 313 * <div class="en">Use a custom UI interface.The interface is called before {@link #detect(Bundle, LivenessDetectListener)}.</div> 314 * 315 * @throws LivenessDetectException 316 * @since V3.19.00 317 */ 318 void setFaceUICallBack(IFaceUIManager manager) throws LivenessDetectException; 319 320 /** 321 * <div class="zh">初始化活检相机。</div> <div class="en">Initialize the liveness detection camera.</div> 322 * 323 * @param bundle <div class="zh">活体检测配置。 324 * <table border="1"> 325 * <tr> 326 * <th>Key</th> 327 * <th>类型</th> 328 * <th>说明</th> 329 * </tr> 330 * <tr> 331 * <td>checkQuality</td> 332 * <td>boolean</td> 333 * <td>true:进行质量检测;false:不质量检测。默认不开启质量检测。<br>如果开启会有以下提示: <br>1.离得太远: 请往前移一点 <br> 334 * 2.人脸有角度或者闭眼(大于30度): 请保持脸部端正 <br>3.脸部有遮挡 <br>4.请摘下口罩<br>5.请摘下墨镜<br>6.多人脸<br> 7.假体: 个人检测失败 335 * </td> 336 * </tr> 337 * </table> 338 * </div> 339 * <div class="en">Liveness detection configuration. 340 * <table border="1"> 341 * <tr> 342 * <th>Key</th> 343 * <th>Type</th> 344 * <th>Instructions</th> 345 * </tr> 346 * <tr> 347 * <td>checkQuality</td> 348 * <td>boolean</td> 349 * <td>True: check the quality; false: do not check the quality. Quality check is not performed by default.<br> 350 * If check the quality, the following prompts will appear:<br>1.It's too far: please move forward a little <br> 351 * 2.Face with Angle or closed eyes (> 30 degrees): Keep face straight<br>3.The face is covered<br> 352 * 4.Please take off the mask<br>5.Please take off the sunglasses<br> 6.Multiple faces<br>7.Prosthesis: Detection failed 353 * </td> 354 * </tr> 355 * </table> 356 * </div> 357 * @throws LivenessDetectException LivenessDetectException 358 * @since V3.24.00 359 */ 360 void init(Bundle bundle) throws LivenessDetectException; 361 362 /** 363 * <div class="zh">获取银联认证的摄像头型号。</div> <div class="en">Get UnionPay certified camera model.</div> 364 * 365 * @return <div class="zh">摄像头型号。</div> <div class="en">Camera model.</div> 366 * @throws LivenessDetectException LivenessDetectException 367 * @since V3.24.00 368 */ 369 String getCameraModel() throws LivenessDetectException; 370 371 /** 372 * <div class="zh">设置数据预览回调。</div> <div class="en">Set data preview callback.</div> 373 * @param callback <div class="zh">数据预览回调。</div> <div class="en">Data preview callback.</div> 374 * @throws LivenessDetectException LivenessDetectException 375 * @since V3.24.00 376 */ 377 void setLiteUICallback(IPreviewFrame callback) throws LivenessDetectException; 378 379 /** 380 * <div class="zh">进行无界面人脸活体检测,预览由客户自定义实现。</div> 381 * <div class="en">The faceless live detection is performed, and the preview is customized by the customer.</div> 382 * 383 * @param listener {@link LivenessDetectListener} 384 * @throws LivenessDetectException LivenessDetectException 385 * @since V3.24.00 386 */ 387 void detectLite(LivenessDetectListener listener) throws LivenessDetectException; 388 389 /** 390 * 391 * <div class="zh">活体检测监听者。</div> <div class="en">Liveness detect listener.</div> 392 * 393 * @since V3.19.00 394 */ 395 interface LivenessDetectListener{ 396 /** 397 * <div class="zh">活体检测成功。</div> <div class="en">Liveness detect success.</div> 398 * 399 * @param results <div class="zh">活体检测结果。{@link LivenessDetectResult}</div> <div class="en">Liveness detect results.{@link LivenessDetectResult}</div> 400 * @since V3.19.00 401 */ 402 void onSuccess(List<LivenessDetectResult> results); 403 /** 404 * <div class="zh">活体检测失败。</div> <div class="en">Liveness detect fail.</div> 405 * @param errCode <div class="zh">异常码。 406 * <ul> 407 * <li>-1:设备未连接。</li> 408 * <li>-2:授权失败,请检查网络是否可用。</li> 409 * <li>-3:活体检测超时。</li> 410 * <li>-4:取消活体检测。</li> 411 * <li>-5:支付金额格式错误。</li> 412 * <li>-6:使用自定义UI界面时,未设置检测区域坐标。</li> 413 * <li>-7:未将FaceUIService添加到ServiceManager。</li> 414 * </ul></div> <div class="en">Error code. 415 * <ul> 416 * <li>-1:Device not connected.</li> 417 * <li>-2:Authorization failed. Please check whether the network is available.</li> 418 * <li>-3:Liveness detect timeout.</li> 419 * <li>-4:Cancel liveness detect.</li> 420 * <li>-4:Payment amount format error.</li> 421 * <li>-6:When using a custom UI interface, the detection area coordinates are not set.</li> 422 * <li>-7:FaceUIService was not added to the ServiceManager.</li> 423 * </ul></div> 424 * @param msg <div class="zh">错误信息。</div> <div class="en">Error message.</div> 425 * @since V3.19.00 426 */ 427 void onError(int errCode, String msg); 428 429 /** 430 * <div class="zh">相机初始化到可预览耗时。</div> <div class="en">Time taken for camera initialization to be previewed.</div> 431 * 432 * @param time <div class="zh">相机初始化到可预览耗时。</div> <div class="en">Time taken for camera initialization to be previewed.</div> 433 * @since V3.19.00 434 */ 435 void onInitTime(long time); 436 437 /** 438 * <div class="zh">活检耗时。</div> <div class="en">Time taken for detection.</div> 439 * 440 * @param time <div class="zh">活检耗时。</div> <div class="en">Time taken for detection.</div> 441 * @since V3.19.00 442 */ 443 void onDetectTime(long time); 444 } 445 446 /** 447 * <div class="zh">自定义UI界面的服务。</div> 448 * <div class="en">Custom UI interface services.</div> 449 * @since V3.19.00 450 */ 451 interface IFaceUIManager { 452 /** 453 * <div class="zh">开始活体检测时回调(此时可能还未获取到预览数据)。</div> 454 * <div class="en">Call back at the beginning of the liveness detection (preview data may not be available at this point).</div> 455 * 456 * @param bundle <div class="zh"> 457 * <table border="1"> 458 * <tr> 459 * <th>Key</th> 460 * <th>类型</th> 461 * <th>说明</th> 462 * </tr> 463 * <tr> 464 * <td>timeout</td> 465 * <td>int</td> 466 * <td>超时时间</td> 467 * </tr> 468 * <tr> 469 * <td>amount</td> 470 * <td>String</td> 471 * <td>支付金额</td> 472 * </tr> 473 * </table> 474 * </div> 475 * <div class="en"> 476 * <table border="1"> 477 * <tr> 478 * <th>Key</th> 479 * <th>Type</th> 480 * <th>Instructions</th> 481 * </tr> 482 * <tr> 483 * <td>timeout</td> 484 * <td>int</td> 485 * <td>Timeout</td> 486 * </tr> 487 * <tr> 488 * <td>amount</td> 489 * <td>String</td> 490 * <td>Amount spent</td> 491 * </tr> 492 * </table> 493 * </div> 494 * @since V3.19.00 495 */ 496 void startPreview(Bundle bundle) ; 497 498 /** 499 * <div class="zh">活体检测镜头可以获取到预览数据时回调。</div> 500 * <div class="en">Call back when the camera can get preview data.</div> 501 * 502 * @since V3.19.00 503 */ 504 void showPreview(); 505 506 /** 507 * <div class="zh">检测时的提示信息。</div> <div class="en">Prompt information during detection.</div> 508 * 509 * @param code <div class="zh"> 510 * <ul> 511 * <li>-10000:人脸不在检测区域。</li> 512 * <li>-10001:距离太远。</li> 513 * <li>-10002:距离太近。</li> 514 * <li>-10003:人脸角度大。</li> 515 * <li>-10004:口罩遮挡。</li> 516 * <li>-10005:墨镜眼睛部位遮挡。</li> 517 * <li>-10006:脸部有遮挡。</li> 518 * <li>-10007:多人脸。</li> 519 * </ul> 520 * </div> 521 * <div class="en"> 522 * <ul> 523 * <li>-10000:The face is not in the detection area.</li> 524 * <li>-10001:The distance is too far.</li> 525 * <li>-10002:The distance is too close.</li> 526 * <li>-10003:Face angle is large.</li> 527 * <li>-10004:Face mask.</li> 528 * <li>-10005:The eye part of sunglasses is blocked.</li> 529 * <li>-10006:The face is covered.</li> 530 * <li>-10007:Multiple faces.</li> 531 * </ul> 532 * </div> 533 * @since V3.19.00 534 */ 535 void setMessage(int code); 536 537 /** 538 * <div class="zh">停止活体检测时回调。</div> <div class="en">Call back when liveness detection is stopped.</div> 539 * @since V3.19.00 540 */ 541 void stopPreview(); 542 543 /** 544 * <div class="zh">活体检测结束时回调。</div> <div class="en">Call back when liveness detection is finished.</div> 545 * @since V3.19.00 546 */ 547 void detectFinish(); 548 } 549 550 /** 551 * <div class="zh">数据预览回调。</div> <div class="en">Data preview callback.</div> 552 * @since V3.24.00 553 */ 554 interface IPreviewFrame { 555 /** 556 * <div class="zh">数据预览回调。</div> <div class="en">Data preview callback.</div> 557 * @param data <div class="zh">预览数据。</div> <div class="en">Preview data.</div> 558 */ 559 void onPreviewFrame(byte[] data); 560 } 561}