当前位置:网站首页>人脸注册,解锁,响应,一网打尽

人脸注册,解锁,响应,一网打尽

2022-06-23 12:59:00 liujun3512159

现代智能手机,基本上都有人脸解锁功能,那他是怎么实现的哦?下面从代码角度来分析下他。

先上流程图

人脸解锁,都要先录入(这部分后面会出其他博客),再注册,再人脸解锁,响应,下面从代码角度来分析他。

先从锁屏部分的类KeyguardUpdateMonitor入手,下面是人脸服务注册方法。

private void startListeningForFace() {
        final int userId = getCurrentUser();
        final boolean unlockPossible = isUnlockWithFacePossible(userId);
        if (mFaceCancelSignal != null) {
            Log.e(TAG, "Cancellation signal is not null, high chance of bug in face auth lifecycle"
                    + " management. Face state: " + mFaceRunningState
                    + ", unlockPossible: " + unlockPossible);
        }

        if (mFaceRunningState == BIOMETRIC_STATE_CANCELLING) {
            setFaceRunningState(BIOMETRIC_STATE_CANCELLING_RESTARTING);
            return;
        } else if (mFaceRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
            // Waiting for ERROR_CANCELED before requesting auth again
            return;
        }
        if (DEBUG) Log.v(TAG, "startListeningForFace(): " + mFaceRunningState);

        if (unlockPossible) {
            mFaceCancelSignal = new CancellationSignal();

            // This would need to be updated for multi-sensor devices
            final boolean supportsFaceDetection = !mFaceSensorProperties.isEmpty()
                    && mFaceSensorProperties.get(0).supportsFaceDetection;
            mFaceAuthUserId = userId;
            if (isEncryptedOrLockdown(userId) && supportsFaceDetection) {
                mFaceManager.detectFace(mFaceCancelSignal, mFaceDetectionCallback, userId);
            } else {
                final boolean isBypassEnabled = mKeyguardBypassController != null
                        && mKeyguardBypassController.isBypassEnabled();
                mFaceManager.authenticate(null /* crypto */, mFaceCancelSignal,
                        mFaceAuthenticationCallback, null /* handler */, userId, isBypassEnabled);
            }
            setFaceRunningState(BIOMETRIC_STATE_RUNNING);
        }
    }

第31行,人脸注册,这里要注意下变量mFaceAuthenticationCallback,这是回调接口对象,底层设别结果的回传信息,会通过这个变量对象告知用户人脸解锁成功或失败或错误,等等。

    @VisibleForTesting
    final FaceManager.AuthenticationCallback mFaceAuthenticationCallback
            = new FaceManager.AuthenticationCallback() {

                @Override
                public void onAuthenticationFailed() {
                    handleFaceAuthFailed();
                    if (mKeyguardBypassController != null) {
                        mKeyguardBypassController.setUserHasDeviceEntryIntent(false);
                    }
                }

                @Override
                public void onAuthenticationSucceeded(FaceManager.AuthenticationResult result) {
                    Trace.beginSection("KeyguardUpdateMonitor#onAuthenticationSucceeded");
                    handleFaceAuthenticated(result.getUserId(), result.isStrongBiometric());
                    Trace.endSection();

                    if (mKeyguardBypassController != null) {
                        mKeyguardBypassController.setUserHasDeviceEntryIntent(false);
                    }
                }

                @Override
                public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
                    handleFaceHelp(helpMsgId, helpString.toString());
                }

                @Override
                public void onAuthenticationError(int errMsgId, CharSequence errString) {
                    handleFaceError(errMsgId, errString.toString());
                    if (mKeyguardBypassController != null) {
                        mKeyguardBypassController.setUserHasDeviceEntryIntent(false);
                    }
                }

                @Override
                public void onAuthenticationAcquired(int acquireInfo) {
                    handleFaceAcquired(acquireInfo);
                }
    };

后面在设别结果回传的时候,再讨论。

回到代码mFaceManager#authenticate 部分,讨论下变量mFaceManager是如何定义的。

在KeyguardUpdateMonitor类的构造函数中定义的,如下,显然这是一个系统服务。

if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE)) {
            mFaceManager = (FaceManager) context.getSystemService(Context.FACE_SERVICE);
            mFaceSensorProperties = mFaceManager.getSensorPropertiesInternal();
        }

搜索关键字Context.FACE_SERVICE,在SystemServiceRegistry类中实现了系统服务注册。

registerService(Context.FACE_SERVICE, FaceManager.class,
                new CachedServiceFetcher<FaceManager>() {
                    @Override
                    public FaceManager createService(ContextImpl ctx)
                            throws ServiceNotFoundException {
                        final IBinder binder;
                        if (ctx.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.O) {
                            binder = ServiceManager.getServiceOrThrow(Context.FACE_SERVICE);
                        } else {
                            binder = ServiceManager.getService(Context.FACE_SERVICE);
                        }
                        IFaceService service = IFaceService.Stub.asInterface(binder);
                        return new FaceManager(ctx.getOuterContext(), service);
                    }
                });

注意第12,13行,会获得跨进程对象FaceService对象实例,然后绑定到FaceManager系统对象实例中,然后在mFaceManager#authenticate方法中,使用mService 变量,调用到FaceService对象实例下的authenticate方法。

 @RequiresPermission(USE_BIOMETRIC_INTERNAL)
    public void authenticate(@Nullable CryptoObject crypto, @Nullable CancellationSignal cancel,
            @NonNull AuthenticationCallback callback, @Nullable Handler handler, int userId,
            boolean isKeyguardBypassEnabled) {
        if (callback == null) {
            throw new IllegalArgumentException("Must supply an authentication callback");
        }

        if (cancel != null && cancel.isCanceled()) {
            Slog.w(TAG, "authentication already canceled");
            return;
        }

        if (mService != null) {
            try {
                useHandler(handler);
                mAuthenticationCallback = callback;
                mCryptoObject = crypto;
                final long operationId = crypto != null ? crypto.getOpId() : 0;
                Trace.beginSection("FaceManager#authenticate");
                final long authId = mService.authenticate(mToken, operationId, userId,
                        mServiceReceiver, mContext.getOpPackageName(), isKeyguardBypassEnabled);
                if (cancel != null) {
                    cancel.setOnCancelListener(new OnAuthenticationCancelListener(authId));
                }
            } catch (RemoteException e) {
                Slog.w(TAG, "Remote exception while authenticating: ", e);
                // Though this may not be a hardware issue, it will cause apps to give up or
                // try again later.
                callback.onAuthenticationError(FACE_ERROR_HW_UNAVAILABLE,
                        getErrorString(mContext, FACE_ERROR_HW_UNAVAILABLE,
                                0 /* vendorCode */));
            } finally {
                Trace.endSection();
            }
        }
    }

原网站

版权声明
本文为[liujun3512159]所创,转载请带上原文链接,感谢
https://blog.csdn.net/liujun3512159/article/details/125419871

随机推荐