Android Keyguard--灭屏锁屏流程

1.PowerManagerService和PhoneWindowMangerService主要调用了Keyguard的onStartedGoingToSleep和onFinishedGoingToSleep

@/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java#6676
public void init(Context context, IWindowManager windowManager,
2127        if (!mPowerManager.isInteractive()) {
2128            startedGoingToSleep(WindowManagerPolicy.OFF_BECAUSE_OF_USER);
2129            finishedGoingToSleep(WindowManagerPolicy.OFF_BECAUSE_OF_USER);
2130        }

@@frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
        @Override // Binder call
        public void wakeUp(long eventTime, String reason, String opPackageName) {
            if (eventTime > SystemClock.uptimeMillis()) {
                throw new IllegalArgumentException("event time must not be in the future");
            }

            mContext.enforceCallingOrSelfPermission(
                    android.Manifest.permission.DEVICE_POWER, null);

            final int uid = Binder.getCallingUid();
            final long ident = Binder.clearCallingIdentity();
            try {
                wakeUpInternal(eventTime, reason, uid, opPackageName, uid);
            } finally {
                Binder.restoreCallingIdentity(ident);
            }
        }


    private void wakeUpInternal(long eventTime, String reason, int uid, String opPackageName,
            int opUid) {
        synchronized (mLock) {
            if (wakeUpNoUpdateLocked(eventTime, reason, uid, opPackageName, opUid)) {
                updatePowerStateLocked();
            }
        }
    }

 private boolean wakeUpNoUpdateLocked(long eventTime, String reason, int reasonUid,
            String opPackageName, int opUid) {
        if (DEBUG_SPEW) {
            Slog.d(TAG, "wakeUpNoUpdateLocked: eventTime=" + eventTime + ", uid=" + reasonUid);
        }

        Trace.traceBegin(Trace.TRACE_TAG_POWER, "wakeUp");
        try {
            switch (mWakefulness) {
                case WAKEFULNESS_ASLEEP:
                    Slog.i(TAG, "Waking up from sleep (uid " + reasonUid +")...");
                    break;
                case WAKEFULNESS_DREAMING:
                    Slog.i(TAG, "Waking up from dream (uid " + reasonUid +")...");  //熟悉的Log
                    break;
                case WAKEFULNESS_DOZING:
                    Slog.i(TAG, "Waking up from dozing (uid " + reasonUid +")...");
                    break;
            }

            mLastWakeTime = eventTime;
            setWakefulnessLocked(WAKEFULNESS_AWAKE, 0);

            mNotifier.onWakeUp(reason, reasonUid, opPackageName, opUid);
            userActivityNoUpdateLocked(
                    eventTime, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, reasonUid);
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_POWER);
        }
        return true;
    }

@frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
private void setWakefulnessLocked(int wakefulness, int reason) {
    if (mWakefulness != wakefulness) {
        mWakefulness = wakefulness;
        mWakefulnessChanging = true;
        mDirty |= DIRTY_WAKEFULNESS;
        mNotifier.onWakefulnessChangeStarted(wakefulness, reason);
    }
}

340    public void onWakefulnessChangeStarted(final int wakefulness, int reason) {
341        final boolean interactive = PowerManagerInternal.isInteractive(wakefulness);
342        if (DEBUG) {
343            Slog.d(TAG, "onWakefulnessChangeStarted: wakefulness=" + wakefulness
344                    + ", reason=" + reason + ", interactive=" + interactive);
345        }
...
377            handleEarlyInteractiveChange();
378        }
379    }

9    private void 9    private void handleEarlyInteractiveChange() {
400        synchronized (mLock) {
401            if (mInteractive) {
402                // Waking up...
403                mHandler.post(new Runnable() {
404                    @Override
405                    public void run() {
406                        // Note a SCREEN tron event is logged in PowerManagerService.
407                        mPolicy.startedWakingUp();
408                    }
409                });
410
411                // Send interactive broadcast.
412                mPendingInteractiveState = INTERACTIVE_STATE_AWAKE;
413                mPendingWakeUpBroadcast = true;
414                updatePendingBroadcastLocked();
415            } else {
416                // Going to sleep...
417                // Tell the policy that we started going to sleep.
418                final int why = translateOffReason(mInteractiveChangeReason);
419                mHandler.post(new Runnable() {
420                    @Override
421                    public void run() {
422                        mPolicy.startedGoingToSleep(why);
423                    }
424                });
425            }
426        }
427    }() {
400        synchronized (mLock) {
401            if (mInteractive) {
402                // Waking up...
403                mHandler.post(new Runnable() {
404                    @Override
405                    public void run() {
406                        // Note a SCREEN tron event is logged in PowerManagerService.
407                        mPolicy.startedWakingUp();
408                    }
409                });
410
411                // Send interactive broadcast.
412                mPendingInteractiveState = INTERACTIVE_STATE_AWAKE;
413                mPendingWakeUpBroadcast = true;
414                updatePendingBroadcastLocked();
415            } else {
416                // Going to sleep...
417                // Tell the policy that we started going to sleep.
418                final int why = translateOffReason(mInteractiveChangeReason);
419                mHandler.post(new Runnable() {
420                    @Override
421                    public void run() {
422                        mPolicy.startedGoingToSleep(why);
423                    }
424                });
425            }
426        }
427    }

    // Called on the PowerManager's Notifier thread.
    @Override
    public void startedGoingToSleep(int why) {
        if (DEBUG_WAKEUP) Slog.i(TAG, "Started going to sleep... (why=" + why + ")");
        mCameraGestureTriggeredDuringGoingToSleep = false;
        mGoingToSleep = true;
        if (mKeyguardDelegate != null) {
            mKeyguardDelegate.onStartedGoingToSleep(why);
        }
    }

//power key press -- goToSleep
1420    private void powerPress(long eventTime, boolean interactive, int count) {
1421        if (mScreenOnEarly && !mScreenOnFully) {
1422            Slog.i(TAG, "Suppressed redundant power key press while "
1423                    + "already in the process of turning the screen on.");
1424            return;
1425        }

1431        } else if (interactive && !mBeganFromNonInteractive) {
1432            switch (mShortPressOnPowerBehavior) {
1433                case SHORT_PRESS_POWER_NOTHING:
1434                    break;
1435                case SHORT_PRESS_POWER_GO_TO_SLEEP:
1436                    goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0);
1437                    break;
1438                case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP:
1439                    goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,
1440                            PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
1441                    break;
1442                case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP_AND_GO_HOME:
1443                    goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,
1444                            PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
1445                    launchHomeFromHotKey();
1446                    break;
...
1464            }
1465        }
1466    }

1468    private void goToSleep(long eventTime, int reason, int flags) {
1469        mRequestedOrGoingToSleep = true;
1470        mPowerManager.goToSleep(eventTime, reason, flags);
1471    }

2.KeyguardViewMediator

@frameworks/base/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java

    public void onStartedGoingToSleep(int why) {
        if (DEBUG) Log.d(TAG, "onStartedGoingToSleep(" + why + ")");  //why power灭屏是2
        synchronized (this) {
            mDeviceInteractive = false;
            mGoingToSleep = true;

            // Lock immediately based on setting if secure (user has a pin/pattern/password).
            // This also "locks" the device when not secure to provide easy access to the
            // camera while preventing unwanted input.
            int currentUser = KeyguardUpdateMonitor.getCurrentUser();
            final boolean lockImmediately =
                    mLockPatternUtils.getPowerButtonInstantlyLocks(currentUser)
                            || !mLockPatternUtils.isSecure(currentUser);  //lockImmediately就是设置里面的即时锁屏开关
            long timeout = getLockTimeout(KeyguardUpdateMonitor.getCurrentUser());
            mLockLater = false;
            if (mExitSecureCallback != null) {
                if (DEBUG) Log.d(TAG, "pending exit secure callback cancelled");
                try {
                    mExitSecureCallback.onKeyguardExitResult(false);
                } catch (RemoteException e) {
                    Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e);
                }
                mExitSecureCallback = null;
                if (!mExternallyEnabled) {
                    hideLocked();
                }
            } else if (mShowing) {
                mPendingReset = true; //有个异常走这里,因为指纹模式改为WAKE_UNLOCK导致
            } else if ((why == WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT && timeout > 0)
                    || (why == WindowManagerPolicy.OFF_BECAUSE_OF_USER && !lockImmediately)) {
                doKeyguardLaterLocked(timeout);
                mLockLater = true;
            } else if (!mLockPatternUtils.isLockScreenDisabled(currentUser)) {
                mPendingLock = true; //正常走这里mPendingLock
            }

            if (mPendingLock) {
                playSounds(true); //然后播放声音
            }
        }
        KeyguardUpdateMonitor.getInstance(mContext).dispatchStartedGoingToSleep(why);
        notifyStartedGoingToSleep();    //notifyStartedGoingToSleep
    }
    
    
    
    public void onFinishedGoingToSleep(int why, boolean cameraGestureTriggered) {
        if (DEBUG) Log.d(TAG, "onFinishedGoingToSleep(" + why + ")");
        synchronized (this) {
            mDeviceInteractive = false;
            mGoingToSleep = false;

            resetKeyguardDonePendingLocked();
            mHideAnimationRun = false;

            notifyFinishedGoingToSleep(); //notify finish

            if (cameraGestureTriggered) {
                Log.i(TAG, "Camera gesture was triggered, preventing Keyguard locking.");

                // Just to make sure, make sure the device is awake.
                mContext.getSystemService(PowerManager.class).wakeUp(SystemClock.uptimeMillis(),
                        "com.android.systemui:CAMERA_GESTURE_PREVENT_LOCK");
                mPendingLock = false;
                mPendingReset = false;
            }

            if (mPendingReset) {
                resetStateLocked();
                mPendingReset = false;
            }

            if (mPendingLock) {
                doKeyguardLocked(null); //正常走这里
                mPendingLock = false;
            }

            // We do not have timeout and power button instant lock setting for profile lock.
            // So we use the personal setting if there is any. But if there is no device
            // we need to make sure we lock it immediately when the screen is off.
            if (!mLockLater && !cameraGestureTriggered) {
                doKeyguardForChildProfilesLocked();
            }

        }
        KeyguardUpdateMonitor.getInstance(mContext).dispatchFinishedGoingToSleep(why);
    }
    
        /**
     * Enable the keyguard if the settings are appropriate.
     */
    private void doKeyguardLocked(Bundle options) {
        // if another app is disabling us, don't show
        if (!mExternallyEnabled) {
            if (DEBUG) Log.d(TAG, "doKeyguard: not showing because externally disabled");

            // note: we *should* set mNeedToReshowWhenReenabled=true here, but that makes
            // for an occasional ugly flicker in this situation:
            // 1) receive a call with the screen on (no keyguard) or make a call
            // 2) screen times out
            // 3) user hits key to turn screen back on
            // instead, we reenable the keyguard when we know the screen is off and the call
            // ends (see the broadcast receiver below)
            // TODO: clean this up when we have better support at the window manager level
            // for apps that wish to be on top of the keyguard
            return;
        }

        // if the keyguard is already showing, don't bother
        if (mStatusBarKeyguardViewManager.isShowing()) {
            if (DEBUG) Log.d(TAG, "doKeyguard: not showing because it is already showing");
            resetStateLocked();
            return;
        }

        // In split system user mode, we never unlock system user.
        if (!mustNotUnlockCurrentUser()
                || !mUpdateMonitor.isDeviceProvisioned()) {

            // if the setup wizard hasn't run yet, don't show
            final boolean requireSim = !SystemProperties.getBoolean("keyguard.no_require_sim", false);
            final boolean absent = SubscriptionManager.isValidSubscriptionId(
                    mUpdateMonitor.getNextSubIdForState(ABSENT));
            final boolean disabled = SubscriptionManager.isValidSubscriptionId(
                    mUpdateMonitor.getNextSubIdForState(IccCardConstants.State.PERM_DISABLED));
            final boolean lockedOrMissing = mUpdateMonitor.isSimPinSecure()
                    || ((absent || disabled) && requireSim);

            if (!lockedOrMissing && shouldWaitForProvisioning()) {
                if (DEBUG) Log.d(TAG, "doKeyguard: not showing because device isn't provisioned"
                        + " and the sim is not locked or missing");
                return;
            }

            boolean forceShow = options != null && options.getBoolean(OPTION_FORCE_SHOW, false);
            if (mLockPatternUtils.isLockScreenDisabled(KeyguardUpdateMonitor.getCurrentUser())
                    && !lockedOrMissing && !forceShow) {
                if (DEBUG) Log.d(TAG, "doKeyguard: not showing because lockscreen is off");
                return;
            }

            if (mLockPatternUtils.checkVoldPassword(KeyguardUpdateMonitor.getCurrentUser())) {
                if (DEBUG) Log.d(TAG, "Not showing lock screen since just decrypted");
                // Without this, settings is not enabled until the lock screen first appears
                setShowingLocked(false);
                hideLocked();
                mUpdateMonitor.reportSuccessfulStrongAuthUnlockAttempt();
                return;
            }
        }

        if (DEBUG) Log.d(TAG, "doKeyguard: showing the lock screen");
        showLocked(options);    //showLocked
    }
    
        /**
     * Handle message sent by {@link #showLocked}.
     * @see #SHOW
     */
    private void handleShow(Bundle options) {
        Trace.beginSection("KeyguardViewMediator#handleShow");
        final int currentUser = KeyguardUpdateMonitor.getCurrentUser();
        if (mLockPatternUtils.isSecure(currentUser)) {
            mLockPatternUtils.getDevicePolicyManager().reportKeyguardSecured(currentUser);
        }
        synchronized (KeyguardViewMediator.this) {
            if (!mSystemReady) {
                if (DEBUG) Log.d(TAG, "ignoring handleShow because system is not ready.");
                return;
            } else {
                if (DEBUG) Log.d(TAG, "handleShow"); //走这里
            }

            setShowingLocked(true);
            mStatusBarKeyguardViewManager.show(options);
            mHiding = false;
            mWakeAndUnlocking = false;
            resetKeyguardDonePendingLocked();
            mHideAnimationRun = false;
            adjustStatusBarLocked();
            userActivity();
            mShowKeyguardWakeLock.release();
        }
        mKeyguardDisplayManager.show(); //show
        Trace.endSection();
    }

startedGoingToSleep流程

PhoneWindowManager.java interceptPowerKeyUp -- powerPress-- 
PowerManagerService.java goToSleep -- goToSleepInternal -- goToSleepNoUpdateLocked -- setWakefulnessLocked
onWakefulnessChangeStarted --handleEarlyInteractiveChange  --startedGoingToSleep
Notifier.java mPolicy.startedGoingToSleep

mPolicy.finishedGoingToSleep

Log流程:
Started going to sleep... (why=" + why + ")
onStartedGoingToSleep(" + why
playSounds
notifyStartedGoingToSleep
onFinishedGoingToSleep
doKeyguardLocked
doKeyguard: showing the lock screen
handleShow

猜你喜欢

转载自blog.csdn.net/wd229047557/article/details/84979469