Android Keyguard--指纹解锁流程

参考文章    https://www.jianshu.com/p/b07fb1e48d71

何时开始监听指纹传感器?

先来看下IKeyguardService这个binder接口有哪些回调吧

// 当另一个窗口使用FLAG_SHOW_ON_LOCK_SCREEN解除Keyguard时PhoneWindowManager调用
    public void setOccluded(boolean isOccluded, boolean animate) throws android.os.RemoteException;
    // 添加锁屏状态回调
    public void addStateMonitorCallback(com.android.internal.policy.IKeyguardStateCallback callback) throws android.os.RemoteException;
    // 核验解锁(用于快捷启动)
    public void verifyUnlock(com.android.internal.policy.IKeyguardExitCallback callback) throws android.os.RemoteException;
    // 解除锁屏
    public void dismiss(com.android.internal.policy.IKeyguardDismissCallback callback) throws android.os.RemoteException;
    // 屏保开始(Intent.ACTION_DREAMING_STARTED)
    public void onDreamingStarted() throws android.os.RemoteException;
    // 屏保结束(Intent.ACTION_DREAMING_STOPPED)
    public void onDreamingStopped() throws android.os.RemoteException;
    // 设备开始休眠 reason:OFF_BECAUSE_OF_USER/OFF_BECAUSE_OF_ADMIN/OFF_BECAUSE_OF_TIMEOUT
    public void onStartedGoingToSleep(int reason) throws android.os.RemoteException;
    // 休眠完成
    public void onFinishedGoingToSleep(int reason, boolean cameraGestureTriggered) throws android.os.RemoteException;
    // 设备开始唤醒
    public void onStartedWakingUp() throws android.os.RemoteException;
    // 唤醒完成
    public void onFinishedWakingUp() throws android.os.RemoteException;
    // 正在亮屏
    public void onScreenTurningOn(com.android.internal.policy.IKeyguardDrawnCallback callback) throws android.os.RemoteException;
    // 已经亮屏完成
    public void onScreenTurnedOn() throws android.os.RemoteException;
    // 正在灭屏
    public void onScreenTurningOff() throws android.os.RemoteException;
    // 灭屏完成
    public void onScreenTurnedOff() throws android.os.RemoteException;
    // 外部应用取消Keyguard接口
    public void setKeyguardEnabled(boolean enabled) throws android.os.RemoteException;
    // 开机系统准备完成回调
    public void onSystemReady() throws android.os.RemoteException;
    // 延时锁屏 (用于自动休眠)
    public void doKeyguardTimeout(android.os.Bundle options) throws android.os.RemoteException;
    // 切换用户中
    public void setSwitchingUser(boolean switching) throws android.os.RemoteException;
    // 设置当前用户
    public void setCurrentUser(int userId) throws android.os.RemoteException;
    // 系统启动完成回调
    public void onBootCompleted() throws android.os.RemoteException;
    // Keyguard后面的activity已经绘制完成,可以开始移除壁纸和Keyguard flag
    public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) throws android.os.RemoteException;
    // 通知Keyguard对power键做特殊处理,使设备不进行休眠或唤醒而是启动Home(目前是空实现)
    public void onShortPowerPressedGoHome() throws android.os.RemoteException;

onStartedGoingToSleep/
onFinishedGoingToSleep/
onScreenTurningOff/
onScreenTurnedOff
这四个接口是在power键按下后触发,其中onStartedGoingToSleep最先被触发,他们的
调用顺序我会在后文里讲解。

1.指纹接口注册

//播放声音后,dispatchStartedGoingToSleep,就会开始监听指纹状态

@KeyguardViewMediator.java
771    public void onStartedGoingToSleep(int why) {
772        if (DEBUG) Log.d(TAG, "onStartedGoingToSleep(" + why + ")");
773        synchronized (this) {
...
803            } else if (!mLockPatternUtils.isLockScreenDisabled(currentUser)) {
804                mPendingLock = true;
805            }
806
807            if (mPendingLock) {
808                playSounds(true);
809            }
810        }
811        KeyguardUpdateMonitor.getInstance(mContext).dispatchStartedGoingToSleep(why);
812        notifyStartedGoingToSleep();
813    }
814

@frameworks/base/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java#285

1839    public void dispatchStartedGoingToSleep(int why) {
1840        mHandler.sendMessage(mHandler.obtainMessage(MSG_STARTED_GOING_TO_SLEEP, why, 0));
1841    }


284                case MSG_STARTED_GOING_TO_SLEEP:
285                    handleStartedGoingToSleep(msg.arg1);
286                    break;

1017    protected void handleStartedGoingToSleep(int arg1) {
1018        clearFingerprintRecognized();
1019        final int count = mCallbacks.size();
1020        for (int i = 0; i < count; i++) {
1021            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1022            if (cb != null) {
1023                cb.onStartedGoingToSleep(arg1);
1024            }
1025        }
1026        mGoingToSleep = true;
1027        updateFingerprintListeningState();
1028    }


1190    private void updateFingerprintListeningState() {
1191        // If this message exists, we should not authenticate again until this message is
1192        // consumed by the handler
1193        if (mHandler.hasMessages(MSG_FINGERPRINT_AUTHENTICATION_CONTINUE)) {
1194            return;
1195        }
1196        mHandler.removeCallbacks(mRetryFingerprintAuthentication);
1197        boolean shouldListenForFingerprint = shouldListenForFingerprint();
1198        if (mFingerprintRunningState == FINGERPRINT_STATE_RUNNING && !shouldListenForFingerprint) {
1199            stopListeningForFingerprint();
1200        } else if (mFingerprintRunningState != FINGERPRINT_STATE_RUNNING
1201                && shouldListenForFingerprint) {
1202            startListeningForFingerprint();
1203        }
1204    }

1220    private void startListeningForFingerprint() {
1221        if (mFingerprintRunningState == FINGERPRINT_STATE_CANCELLING) {
1222            setFingerprintRunningState(FINGERPRINT_STATE_CANCELLING_RESTARTING);
1223            return;
1224        }
1225        if (DEBUG) Log.v(TAG, "startListeningForFingerprint()"); // Log
1226        int userId = ActivityManager.getCurrentUser();
1227        if (isUnlockWithFingerprintPossible(userId)) {
1228            if (mFingerprintCancelSignal != null) {
1229                mFingerprintCancelSignal.cancel();
1230            }
1231            mFingerprintCancelSignal = new CancellationSignal();
1232            mFpm.authenticate(null, mFingerprintCancelSignal, 0, mAuthenticationCallback, null, userId); //真正监听authenticate,写mAuthenticationCallback
1233            setFingerprintRunningState(FINGERPRINT_STATE_RUNNING);
1234        }
1235    }

2.指纹接口

写这个mAuthenticationCallback,并且重写他的几个方法

818    private FingerprintManager.AuthenticationCallback mAuthenticationCallback
819            = new AuthenticationCallback() {
820
821        @Override
822        public void onAuthenticationFailed() {
823            handleFingerprintAuthFailed();
824        };
825
826        @Override
827        public void onAuthenticationSucceeded(AuthenticationResult result) {
828            Trace.beginSection("KeyguardUpdateMonitor#onAuthenticationSucceeded");
829            handleFingerprintAuthenticated(result.getUserId());
830            Trace.endSection();
831        }
832
833        @Override
834        public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
835            handleFingerprintHelp(helpMsgId, helpString.toString());
836        }
837
838        @Override
839        public void onAuthenticationError(int errMsgId, CharSequence errString) {
840            handleFingerprintError(errMsgId, errString.toString());
841        }
842
843        @Override
844        public void onAuthenticationAcquired(int acquireInfo) {
845            handleFingerprintAcquired(acquireInfo);
846        }
847    };

3.指纹认证成功后调用 onAuthenticationSucceeded

遍历所有KeyguardUpdateMonitorCallback,回调onFingerprintAuthenticated

533    private void handleFingerprintAuthenticated(int authUserId) {
534        Trace.beginSection("KeyGuardUpdateMonitor#handlerFingerPrintAuthenticated");
535        try {
536            final int userId;
537            try {
538                userId = ActivityManager.getService().getCurrentUser().id;
539            } catch (RemoteException e) {
540                Log.e(TAG, "Failed to get current user id: ", e);
541                return;
542            }
543            if (userId != authUserId) {
544                Log.d(TAG, "Fingerprint authenticated for wrong user: " + authUserId);
545                return;
546            }
547            if (isFingerprintDisabled(userId)) {
548                Log.d(TAG, "Fingerprint disabled by DPM for userId: " + userId);
549                return;
550            }
551            onFingerprintAuthenticated(userId);
552        } finally {
553            setFingerprintRunningState(FINGERPRINT_STATE_STOPPED);
554        }
555        Trace.endSection();
556    }

//遍历 KeyguardUpdateMonitorCallback,进行回调。
486    private void onFingerprintAuthenticated(int userId) {
487        Trace.beginSection("KeyGuardUpdateMonitor#onFingerPrintAuthenticated");
488        mUserFingerprintAuthenticated.put(userId, true);
489        // Update/refresh trust state only if user can skip bouncer
490        if (getUserCanSkipBouncer(userId)) {
491            mTrustManager.unlockedByFingerprintForUser(userId);
492        }
493        // Don't send cancel if authentication succeeds
494        mFingerprintCancelSignal = null;
495        for (int i = 0; i < mCallbacks.size(); i++) {
496            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
497            if (cb != null) {
498                cb.onFingerprintAuthenticated(userId);
499            }
500        }
501
502        mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_FINGERPRINT_AUTHENTICATION_CONTINUE),
503                FINGERPRINT_CONTINUE_DELAY_MS);
504
505        // Only authenticate fingerprint once when assistant is visible
506        mAssistantVisible = false;
507
508        Trace.endSection();
509    }

4.FingerprintUnlockController认证成功,唤醒

frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java#255

189    @Override
190    public void onFingerprintAuthenticated(int userId) {
191        Trace.beginSection("FingerprintUnlockController#onFingerprintAuthenticated");
192        if (mUpdateMonitor.isGoingToSleep()) {
193            mPendingAuthenticatedUserId = userId;
194            Trace.endSection();
195            return;
196        }
197        startWakeAndUnlock(calculateMode()); //这里
198    }

200    public void startWakeAndUnlock(int mode) {
201        // TODO(b/62444020): remove when this bug is fixed
202        Log.v(TAG, "startWakeAndUnlock(" + mode + ")"); //指纹模式解锁模式应该是2,可对比正常情况看
203        boolean wasDeviceInteractive = mUpdateMonitor.isDeviceInteractive();
204        mMode = mode;
205        mHasScreenTurnedOnSinceAuthenticating = false;
206        if (mMode == MODE_WAKE_AND_UNLOCK_PULSING && pulsingOrAod()) {
207            // If we are waking the device up while we are pulsing the clock and the
208            // notifications would light up first, creating an unpleasant animation.
209            // Defer changing the screen brightness by forcing doze brightness on our window
210            // until the clock and the notifications are faded out.
211            mStatusBarWindowManager.setForceDozeBrightness(true);
212        }
213        if (!wasDeviceInteractive) {
214            if (DEBUG_FP_WAKELOCK) {
215                Log.i(TAG, "fp wakelock: Authenticated, waking up..."); //Log fp wakelock: Authenticated, waking up...
216            }
217            mPowerManager.wakeUp(SystemClock.uptimeMillis(), "android.policy:FINGERPRINT");   //wake up 
218        }
219        Trace.beginSection("release wake-and-unlock");
220        releaseFingerprintWakeLock();
221        Trace.endSection();
222        switch (mMode) {
223            case MODE_DISMISS_BOUNCER:
224                Trace.beginSection("MODE_DISMISS");
225                mStatusBarKeyguardViewManager.notifyKeyguardAuthenticated(
226                        false /* strongAuth */);
227                Trace.endSection();
228                break;
229            case MODE_UNLOCK:
230            case MODE_SHOW_BOUNCER:
231                Trace.beginSection("MODE_UNLOCK or MODE_SHOW_BOUNCER");
232                if (!wasDeviceInteractive) {
233                    mStatusBarKeyguardViewManager.notifyDeviceWakeUpRequested();
234                    mPendingShowBouncer = true;
235                } else {
236                    showBouncer();
237                }
238                Trace.endSection();
239                break;
240            case MODE_WAKE_AND_UNLOCK_FROM_DREAM:
241            case MODE_WAKE_AND_UNLOCK_PULSING:
242            case MODE_WAKE_AND_UNLOCK:
243                if (mMode == MODE_WAKE_AND_UNLOCK_PULSING) {
244                    Trace.beginSection("MODE_WAKE_AND_UNLOCK_PULSING");
245                    mStatusBar.updateMediaMetaData(false /* metaDataChanged */,
246                            true /* allowEnterAnimation */);
247                } else if (mMode == MODE_WAKE_AND_UNLOCK){
248                    Trace.beginSection("MODE_WAKE_AND_UNLOCK");
249                    mDozeScrimController.abortDoze();
250                } else {
251                    Trace.beginSection("MODE_WAKE_AND_UNLOCK_FROM_DREAM");
252                    mUpdateMonitor.awakenFromDream();
253                }
254                mStatusBarWindowManager.setStatusBarFocusable(false);
255                mKeyguardViewMediator.onWakeAndUnlocking();
256                mScrimController.setWakeAndUnlocking();
257                mDozeScrimController.setWakeAndUnlocking();
258                if (mStatusBar.getNavigationBarView() != null) {
259                    mStatusBar.getNavigationBarView().setWakeAndUnlocking(true);
260                }
261                Trace.endSection();
262                break;
263            case MODE_ONLY_WAKE:
264            case MODE_NONE:
265                break;
266        }
267        mStatusBar.notifyFpAuthModeChanged();
268        Trace.endSection();
269    }

5.隐藏Keyguard

@frameworks/base/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
    public void onWakeAndUnlocking() {
        Trace.beginSection("KeyguardViewMediator#onWakeAndUnlocking");
        mWakeAndUnlocking = true;
        keyguardDone();
        Trace.endSection();
    }
    
1476    public void keyguardDone() {
1477        Trace.beginSection("KeyguardViewMediator#keyguardDone");
1478        if (DEBUG) Log.d(TAG, "keyguardDone()");
1479        userActivity();
1480        EventLog.writeEvent(70000, 2);
1481        Message msg = mHandler.obtainMessage(KEYGUARD_DONE);
1482        mHandler.sendMessage(msg);
1483        Trace.endSection();
1484    }

1535                case KEYGUARD_DONE:
1536                    Trace.beginSection("KeyguardViewMediator#handleMessage KEYGUARD_DONE");
1537                    handleKeyguardDone();
1538                    Trace.endSection();
1539                    break;


1589    /**
1590     * @see #keyguardDone
1591     * @see #KEYGUARD_DONE
1592     */
1593    private void handleKeyguardDone() {
1594        Trace.beginSection("KeyguardViewMediator#handleKeyguardDone");
1595        final int currentUser = KeyguardUpdateMonitor.getCurrentUser();
1596        mUiOffloadThread.submit(() -> {
1597            if (mLockPatternUtils.isSecure(currentUser)) {
1598                mLockPatternUtils.getDevicePolicyManager().reportKeyguardDismissed(currentUser);
1599            }
1600        });
1601        if (DEBUG) Log.d(TAG, "handleKeyguardDone"); //Log
1602        synchronized (this) {
1603            resetKeyguardDonePendingLocked();
1604        }
1605
1606        mUpdateMonitor.clearFailedUnlockAttempts();
1607        mUpdateMonitor.clearFingerprintRecognized();
1608
1609        if (mGoingToSleep) {
1610            Log.i(TAG, "Device is going to sleep, aborting keyguardDone");
1611            return;
1612        }
1613        if (mExitSecureCallback != null) {
1614            try {
1615                mExitSecureCallback.onKeyguardExitResult(true /* authenciated */);
1616            } catch (RemoteException e) {
1617                Slog.w(TAG, "Failed to call onKeyguardExitResult()", e);
1618            }
1619
1620            mExitSecureCallback = null;
1621
1622            // after succesfully exiting securely, no need to reshow
1623            // the keyguard when they've released the lock
1624            mExternallyEnabled = true;
1625            mNeedToReshowWhenReenabled = false;
1626            updateInputRestricted();
1627        }
1628
1629        handleHide(); //hide
1630        Trace.endSection();
1631    }
1632
    
1787    /**
1788     * Handle message sent by {@link #hideLocked()}
1789     * @see #HIDE
1790     */
1791    private void handleHide() {
1792        Trace.beginSection("KeyguardViewMediator#handleHide");
1793        synchronized (KeyguardViewMediator.this) {
1794            if (DEBUG) Log.d(TAG, "handleHide");
1795
1796            if (mustNotUnlockCurrentUser()) {
1797                // In split system user mode, we never unlock system user. The end user has to
1798                // switch to another user.
1799                // TODO: We should stop it early by disabling the swipe up flow. Right now swipe up
1800                // still completes and makes the screen blank.
1801                if (DEBUG) Log.d(TAG, "Split system user, quit unlocking.");
1802                return;
1803            }
1804            mHiding = true;
1805
1806            if (mShowing && !mOccluded) {
1807                mKeyguardGoingAwayRunnable.run();  //这里
1808            } else {
1809                handleStartKeyguardExitAnimation(
1810                        SystemClock.uptimeMillis() + mHideAnimation.getStartOffset(),
1811                        mHideAnimation.getDuration());
1812            }
1813        }
1814        Trace.endSection();
1815    }
1816

1817    private void handleStartKeyguardExitAnimation(long startTime, long fadeoutDuration) {
1818        Trace.beginSection("KeyguardViewMediator#handleStartKeyguardExitAnimation");
1819        if (DEBUG) Log.d(TAG, "handleStartKeyguardExitAnimation startTime=" + startTime
1820                + " fadeoutDuration=" + fadeoutDuration);
1821        synchronized (KeyguardViewMediator.this) {
1822
1823            if (!mHiding) {
1824                return;
1825            }
1826            mHiding = false;
1841                playSounds(false);
1842            }
1843
1844            mWakeAndUnlocking = false;
1845            setShowingLocked(false);  //set mshow = false
1846            mDismissCallbackRegistry.notifyDismissSucceeded();
1847            mStatusBarKeyguardViewManager.hide(startTime, fadeoutDuration);
1848            resetKeyguardDonePendingLocked();
1849            mHideAnimationRun = false;
1850            adjustStatusBarLocked();
1851            sendUserPresentBroadcast();
1852            mUpdateMonitor.setKeyguardGoingAway(false /* goingAway */);
1853        }
1854        Trace.endSection();
1855    }

Log流程:


FingerprintUnlockController startWakeAndUnlock(2)
fp wakelock: Authenticated, waking up..
mPowerManager.wakeUp
keyguardDone
handleKeyguardDone
handleHide
handleStartKeyguardExitAnimation

展开阅读全文

没有更多推荐了,返回首页