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}