Android6.0キーガードロック画面の読み込みプロセスの分析

ロック画面インターフェースの読み込みは、通常、Androidでは2つの方法でトリガーされます。AndroidシステムがオンになってからscreenOff(画面がオフ)になり、次にscreenOnになります。

初見

Androidシステムがオンになっているときのロック画面の読み込みプロセス
まず、システムの起動プロセス中に、SystemServer.javaのstartOtherServices()メソッドに入ります。

WindowManagerServiceを初期化します。

wm = WindowManagerService.main(context, inputManager,
                    mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
                    !mFirstBoot, mOnlyCore);
systemReady()メソッドを呼び出して、システムを起動する準備ができていることを示します。

try {
            wm.systemReady();
        } catch (Throwable e) {
            reportWtf("making Window Manager Service ready", e);
        }
WindowManagerPolicy.javaのsystemReady()メソッドを呼び出します
public void systemReady() {
        mPolicy.systemReady();
    }
そして、このmPolicyは、PhoneWindowManager.javaの構築メソッドによって構築されます。

final WindowManagerPolicy mPolicy = new PhoneWindowManager();
つまり、PhoneWindowManager.javaのsystemReady()メソッドが最終的に呼び出され、KeyguardServiceDelegateオブジェクトがこのメソッドで初期化され、systemReady()メソッドが呼び出されます。

 mKeyguardDelegate = new KeyguardServiceDelegate(mContext);
 mKeyguardDelegate.onSystemReady();
KeyguardServiceDelegate.javaクラスで、引き続きKeyguardServiceWrapper.javaのsystemReady()メソッドを呼び出します。

public void onSystemReady() {
        if (mKeyguardService != null) {
            mKeyguardService.onSystemReady();
        } else {
            mKeyguardState.systemIsReady = true;
        }
    }
aidlを使用して、KeyguardServiceWrapper.javaのKeyguardService.javaのonSystemReady()メソッドを呼び出します。

    @Override // Binder interface
    public void onSystemReady() {
        try {
            mService.onSystemReady();
        } catch (RemoteException e) {
            Slog.w(TAG , "Remote Exception", e);
        }
    }
KeyguardService.javaのKeyguardViewMediator.javaのonSystemReady()メソッドを呼び出します。
        @Override // Binder interface
        public void onSystemReady() {
            checkPermission();
            mKeyguardViewMediator.onSystemReady();
        }

最後に、doKeyguardLocked()がKeyguardViewMediator.javaのonSystemReady()メソッドで呼び出され、ロック画面の読み込みプロセスが開始されます。

    /**
     * Let us know that the system is ready after startup.
     */
    public void onSystemReady() {
        mSearchManager = (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE);
        synchronized (this) {
            if (DEBUG) Log.d(TAG, "onSystemReady");
            mSystemReady = true;
            doKeyguardLocked(null);
            mUpdateMonitor.registerCallback(mUpdateCallback);
        }
        // Most services aren't available until the system reaches the ready state, so we
        // send it here when the device first boots.
        maybeSendUserPresentBroadcast();
    }
KeyguardViewMediator.javaのdoKeyguardLocked()メソッド。

    /**
     * Enable the keyguard if the settings are appropriate.
     */
    private void doKeyguardLocked(Bundle options) {
        // if another app is disabling us, don't show
        if (!mExternallyEnabled) {
            return;
        }

        // if the keyguard is already showing, don't bother
        if (mStatusBarKeyguardViewManager.isShowing()) {
            resetStateLocked();
            return;
        }

        // 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(IccCardConstants.State.ABSENT));
        final boolean disabled = SubscriptionManager.isValidSubscriptionId(
                mUpdateMonitor.getNextSubIdForState(IccCardConstants.State.PERM_DISABLED));
        final boolean lockedOrMissing = mUpdateMonitor.isSimPinSecure()
                || ((absent || disabled) && requireSim);

        if (!lockedOrMissing && shouldWaitForProvisioning()) {
            return;
        }

        if (mLockPatternUtils.isLockScreenDisabled(KeyguardUpdateMonitor.getCurrentUser())
                && !lockedOrMissing) {
            return;
        }

        if (mLockPatternUtils.checkVoldPassword(KeyguardUpdateMonitor.getCurrentUser())) {
            // Without this, settings is not enabled until the lock screen first appears
            setShowingLocked(false);
            hideLocked();
            mUpdateMonitor.reportSuccessfulStrongAuthUnlockAttempt();
            return;
        }
        showLocked(options);
    }
1. mExternallyEnabled;デフォルトはtrue、キーガードが他のアプリケーションに表示されない場合、リターンは直接表示されません;
2.キーガードが現在表示されている場合は、無視してリセットします;
3。インストールウィザードが完了していない場合、デバイスが表示され ない初期バインドおよびその他の操作が完了した後、キーガードを表示しない;
4.現在の画面がオフの場合は、キーガードを表示しない;
5.これがないと、ロック画面が最初に表示されるまで設定が有効になりません(ここでは比較はありません。良いことです)
。6。上記の条件が満たされない場合は、showLocked()メソッドを使用してキーガードの表示を開始します。


msgがSHOWであるというメッセージを送信し、キーガードの表示を開始します。

    /**
     * Send message to keyguard telling it to show itself
     * @see #handleShow
     */
    private void showLocked(Bundle options) {
        if (DEBUG) Log.d(TAG, "showLocked");
        // ensure we stay awake until we are finished displaying the keyguard
        mShowKeyguardWakeLock.acquire();
        Message msg = mHandler.obtainMessage(SHOW, options);
        mHandler.sendMessage(msg);
    }
handleShow()メソッドを呼び出します。

case SHOW:
    handleShow((Bundle) msg.obj);
    break;
handleShow()メソッドでStatusBarKeyguardViewManager.javaのshow()メソッドを呼び出します。

    /**
     * Handle message sent by {@link #showLocked}.
     * @see #SHOW
     */
    private void handleShow(Bundle options) {
        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;
            updateActivityLockScreenState();
            adjustStatusBarLocked();
            userActivity();

            mShowKeyguardWakeLock.release();
        }
        mKeyguardDisplayManager.show();
    }
StatusBarKeyguardViewManager.javaのshow()メソッドに呼び出されます

    public void show(Bundle options) {
        mShowing = true;
        mStatusBarWindowManager.setKeyguardShowing(true);
        mScrimController.abortKeyguardFadingOut();
        reset();
    }
StatusBarKeyguardViewManager.javaは
、ステータスバーのキーガードによるステータスバーウィンドウのステータスの作成、表示、非表示、およびリセットを担当します。Java は、すべてのステータスバーウィンドウの状態の論理管理を担当し
ます。1。StatusBarKeyguardViewManagerのsetKeyguardShowing()メソッド。 javaは、apply()メソッドを使用してmStatusBarViewのフラグを更新するために使用されます。
    public void setKeyguardShowing(boolean showing) {
        mCurrentState.keyguardShowing = showing;
        apply(mCurrentState);
    }
2. reset()メソッドを呼び出してmStatusBarViewの状態をリセットします。まず、reset()メソッドを確認します。

    /**
     * Reset the state of the view.
     */
    public void reset() {
        if (mShowing) {
            if (mOccluded) {
                mPhoneStatusBar.hideKeyguard();
                mPhoneStatusBar.stopWaitingForKeyguardExit();
                mBouncer.hide(false /* destroyView */);
            } else {
                showBouncerOrKeyguard();
            }
            KeyguardUpdateMonitor.getInstance(mContext).sendKeyguardReset();
            updateStates();
        }
    }
reset()メソッドでは、キーガードが他のウィンドウによって中断されているかどうかが判断されます。中断されている場合は、キーガードは表示されません。そうでない場合は、showBouncerOrKeyguard()メソッドが実行されます
。showBouncerOrKeyguard()メソッドは通常のロックの表示を決定するためのKeyguardBouncer.javaのneedsFullscreenBouncer()メソッド画面は引き続きBouncerセキュリティロック画面(パターンロック画面、パスワードロック画面、PINコードロック画面など)です。

    /**
     * Shows the notification keyguard or the bouncer depending on
     * {@link KeyguardBouncer#needsFullscreenBouncer()}.
     */
    private void showBouncerOrKeyguard() {
        if (mBouncer.needsFullscreenBouncer()) {

            // The keyguard might be showing (already). So we need to hide it.
            mPhoneStatusBar.hideKeyguard();
            mBouncer.show(true /* resetSecuritySelection */);
        } else {
            mPhoneStatusBar.showKeyguard();
            mBouncer.hide(false /* destroyView */);
            mBouncer.prepare();
        }
    }
1.従来のロック画面は、通知キーガードと呼ばれる、通常はスライドによってロック解除されるスライド式ロック画面インターフェイスです。このタイプのキーガードはステータスバーと統合されており、PhoneStatusBar.javaのオブジェクトによって直接制御できます
。2。バウンサーセキュリティロック画面;パスワード、パターン、PIMコード、PUKコードなどのロック画面インターフェイスは、KeyguardBouncer.javaを介してshow()とhide()の制御を開始します。
KeyguardBouncer.java的show()方法:
    public void show(boolean resetSecuritySelection) {
        ensureView();
        if (resetSecuritySelection) {
            // showPrimarySecurityScreen() updates the current security method. This is needed in
            // case we are already showing and the current security method changed.
            mKeyguardView.showPrimarySecurityScreen();
        }
        if (mRoot.getVisibility() == View.VISIBLE || mShowingSoon) {
            return;
        }

        // Try to dismiss the Keyguard. If no security pattern is set, this will dismiss the whole
        // Keyguard. If we need to authenticate, show the bouncer.
        if (!mKeyguardView.dismiss()) {
            mShowingSoon = true;

            // Split up the work over multiple frames.
            DejankUtils.postAfterTraversal(mShowRunnable);
        }
    }
1.最初にensureView()メソッドを呼び出して、keyguard_bouncerビューをロードします

    private void ensureView() {
        if (mRoot == null) {
            inflateView();
        }
    }

    private void inflateView() {
        removeView();
        mRoot = (ViewGroup) LayoutInflater.from(mContext).inflate(R.layout.keyguard_bouncer, null);
        mKeyguardView = (KeyguardHostView) mRoot.findViewById(R.id.keyguard_host_view);
        mKeyguardView.setLockPatternUtils(mLockPatternUtils);
        mKeyguardView.setViewMediatorCallback(mCallback);
        mContainer.addView(mRoot, mContainer.getChildCount());
        mRoot.setVisibility(View.INVISIBLE);
        mRoot.setSystemUiVisibility(View.STATUS_BAR_DISABLE_HOME);
    }
2. KeyguardHostView.javaのshowPrimarySecurityScreen()メソッドを呼び出します。

    /**
     * Called when the view needs to be shown.
     */
    public void showPrimarySecurityScreen() {
        if (DEBUG) Log.d(TAG, "show()");
        mSecurityContainer.showPrimarySecurityScreen(false);
    }
KeyguardSecurityContainer.javaのshowPrimarySecurityScreen()メソッドを引き続き呼び出して、最初にロック画面メソッドを取得します。

    /**
     * Shows the primary security screen for the user. This will be either the multi-selector
     * or the user's security method.
     * @param turningOff true if the device is being turned off
     */
    void showPrimarySecurityScreen(boolean turningOff) {
        SecurityMode securityMode = mSecurityModel.getSecurityMode();
        if (DEBUG) Log.v(TAG, "showPrimarySecurityScreen(turningOff=" + turningOff + ")");
        showSecurityScreen(securityMode);
    }
取得したロック画面のsecurityModeをパラメータとしてshowSecurityScreen()メソッドを引き続き呼び出します。このメソッドは主に、securityModeに従ってロック画面ビューを表示するために使用されます。
    /**
     * Switches to the given security view unless it's already being shown, in which case
     * this is a no-op.
     *
     * @param securityMode
     */
    private void showSecurityScreen(SecurityMode securityMode) {
        if (DEBUG) Log.d(TAG, "showSecurityScreen(" + securityMode + ")");

        if (securityMode == mCurrentSecuritySelection) return;

        KeyguardSecurityView oldView = getSecurityView(mCurrentSecuritySelection);
        KeyguardSecurityView newView = getSecurityView(securityMode);

        // Emulate Activity life cycle
        if (oldView != null) {
            oldView.onPause();
            oldView.setKeyguardCallback(mNullCallback); // ignore requests from old view
        }
        if (securityMode != SecurityMode.None) {
            newView.onResume(KeyguardSecurityView.VIEW_REVEALED);
            newView.setKeyguardCallback(mCallback);
        }

        // Find and show this child.
        final int childCount = mSecurityViewFlipper.getChildCount();

        final int securityViewIdForMode = getSecurityViewIdForMode(securityMode);
        for (int i = 0; i < childCount; i++) {
            if (mSecurityViewFlipper.getChildAt(i).getId() == securityViewIdForMode) {
                mSecurityViewFlipper.setDisplayedChild(i);
                break;
            }
        }

        mCurrentSecuritySelection = securityMode;
        mSecurityCallback.onSecurityModeChanged(securityMode,
                securityMode != SecurityMode.None && newView.needsInput());
    }
1.まず、着信securityModeが表示されているかどうかを確認します
。2。getSecurityView()メソッドを呼び出して、指定されたロック画面ビューを取得します
。3。KeyguardSecurityView.javaのonPause()メソッドを呼び出して、古いロック画面ビューの表示を一時停止します。 、onResume()メソッドは新しいロック画面ビューの表示を開始します。KeyguardSecurityView.javaはインターフェイスクラスであり、その内部メソッドは宣言が実装されていないことを除いて抽象的であり、メソッドの実装はすべてこのインターフェイスから継承されたクラスにあります。
キーガードでは、KeyguardAbsKeyInputView.java、KeyguardPasswordView.java、KeyguardPatternView.javaなど。これらのクラスは、このインターフェイスから継承して内部メソッドを実装します。これらのクラスは、特定のロック画面インターフェイスビューの表示です。


起動時に表示されるキーガードの概要:
1。KeyguardViewMediator.javaのonSystemReady()メソッドでdoKeyguardLocked()を呼び出して、ロック画面の読み込みプロセスを開始します
。2。setKeyguardEnabled();他のアプリケーションまたはサービスはsetKeyguardEnabled()メソッドを呼び出すことができます。ロック画面を要求するには;
3。KeyguardViewMediator.javaは、キーガードで主要なスケジューリングの役割を果たし、主に
1)ロック画面のステータスを照会します(現在ロックされているかロック解除されているか)。ロック画面状態では、入力イベントは次のようになります。制限付き。
2)PhoneWindowManager.javaは、mKeyguardDelegateオブジェクト(KeyguardServiceDelegate.java)を介してKeyguardViewMediator.javaを有効にし、そのメソッドを呼び出します
。3)SIMカードのステータス変更に応答し、ロック画面インターフェイスonSimStateChanged();に対応する調整を行います
。キーガードが禁止されている、キーガードが現在表示されているかどうかなど。つまり、ケガードを現在表示できるかどうか、表示できる場合は、引き続きshowLocked()メソッドを呼び出します。5。handleShow()メソッドを
呼び出します。 、StatusBarKeyguardViewManager.javaのshow()を呼び出して、キーガードロック画面インターフェイスの表示を開始します。
6. reset()メソッドを呼び出し、showBouncerOrKeyguard()メソッドを呼び出して、通常のロック画面インターフェイスとセキュリティロック画面インターフェイスのどちらを表示するかを決定します。通常のロック画面が表示される場合は、showKeyguard()またはhideKeyguard()を直接呼び出します。 PhoneStatusBar.javaのメソッド;セキュリティロックが表示されている場合画面インターフェイスはKeyguardBouncer.javaクラスに転送されます;
7.KeyguardBouncer.javaのshow()メソッドを呼び出します; sureView()メソッドを使用してインスタンス化レイアウトをロードします;呼び出しますKeyguardHostView.javaのshowPrimarySecurityScreen()メソッドを使用してセキュリティロック画面インターフェイスを表示します
。8。KeyguardHostView.javaのshowPrimarySecurityScreen()メソッドがKeyguardSecurityContainer.javaのshowPrimarySecurityScreen()メソッドに転送されます。9。showSecurityScreen()メソッドを呼び出します
。ロック画面メソッドに従って異なるロック画面ビューをロードするには;
10。KeyguardSecurityView。Javaはインターフェイスクラスであり、宣言が実装されていないことを除いて、その内部メソッドは抽象的であり、メソッド実装はすべてこのインターフェイスから継承されたクラスにあります。
キーガードでは、KeyguardAbsKeyInputView.java、KeyguardPasswordView.java、KeyguardPatternView.javaなど。Keyguard* View.javaは、このインターフェイスから継承して内部メソッドを実装します。これらのクラスは、特定のロック画面インターフェイスビュー表示です。


システムは画面をオフにします。 。オフ後のkeguardのロードプロセス:
Androidシステムの自動スクリーンオフプロセスは、電源ボタン後のスクリーンオフプロセスとは少し異なる場合がありますが、主な分析はスクリーンオフ後にキーガードをロードすることであるため、ロードについてのみ注意する必要がありますシステムがオフになった後のkeguardのプロセス。
次に、電源ボタンを押して画面をオフにしてプロセスを分析する例を示します。
明るい画面の状態で電源ボタンを押すと、一連の判断の後、mPowerManager.goToSleep()メソッドが呼び出されます。 、PowerManagerService.javaのgotoSleepは、aidlを介して呼び出されます。()メソッド:

        @Override // Binder call
        public void goToSleep(long eventTime, int reason, int flags) {
            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 {
                goToSleepInternal(eventTime, reason, flags, uid);
            } finally {
                Binder.restoreCallingIdentity(ident);
            }
        }
引き続きgoToSleepInternal()メソッドを呼び出します。

    private void goToSleepInternal(long eventTime, int reason, int flags, int uid) {
        synchronized (mLock) {
            if (goToSleepNoUpdateLocked(eventTime, reason, flags, uid)) {
                updatePowerStateLocked();
            }
        }
    }
updatePowerStateLocked()メソッドを呼び出してから、このメソッドでfinishWakefulnessChangeIfNeededLocked()メソッドを呼び出します。

    private void finishWakefulnessChangeIfNeededLocked() {
        if (mWakefulnessChanging && mDisplayReady) {
            if (mWakefulness == WAKEFULNESS_DOZING
                    && (mWakeLockSummary & WAKE_LOCK_DOZE) == 0) {
                return; // wait until dream has enabled dozing
            }
            mWakefulnessChanging = false;
            mNotifier.onWakefulnessChangeFinished();
        }
    }
このとき、Notifier.javaのonWakefulnessChangeFinished()メソッドを呼び出します。

    /**
     * Notifies that the device has finished changing wakefulness.
     */
    public void onWakefulnessChangeFinished() {
        if (DEBUG) {
            Slog.d(TAG, "onWakefulnessChangeFinished");
        }

        if (mInteractiveChanging) {
            mInteractiveChanging = false;
            handleLateInteractiveChange();
        }
    }
handleLateInteractiveChange()メソッドを呼び出します。

    /**
     * Handle late interactive state changes once they are finished so that the system can
     * finish pending transitions (such as turning the screen off) before causing
     * applications to change state visibly.
     */
    private void handleLateInteractiveChange() {
        synchronized (mLock) {
            if (mInteractive) {
                // Finished waking up...
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        mPolicy.finishedWakingUp();
                    }
                });
            } else {
                // Finished going to sleep...
                // This is a good time to make transitions that we don't want the user to see,
                // such as bringing the key guard to focus.  There's no guarantee for this
                // however because the user could turn the device on again at any time.
                // Some things may need to be protected by other mechanisms that defer screen on.

                // Cancel pending user activity.
                if (mUserActivityPending) {
                    mUserActivityPending = false;
                    mHandler.removeMessages(MSG_USER_ACTIVITY);
                }

                // Tell the policy we finished going to sleep.
                final int why = translateOffReason(mInteractiveChangeReason);
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 0, why, 0, 0);
                        mPolicy.finishedGoingToSleep(why);
                    }
                });

                // Send non-interactive broadcast.
                mPendingInteractiveState = INTERACTIVE_STATE_ASLEEP;
                mPendingGoToSleepBroadcast = true;
                updatePendingBroadcastLocked();
            }
        }
    }
このメソッドで注意する必要がある2つの文があります:mPolicy.finishedWakingUp()とmPolicy.finishedGoingToSleep();コメントを見て、一方がウェイクアップしていて、もう一方がスリープ操作であることを確認します。電源がオフになっているため。画面には、mPolicy .finishedGoingToSleep()メソッドが表示される必要があります。また、mPolicyはWindowManagerPolicy.javaのオブジェクトであり、このクラスもインターフェイスクラスであり、インターフェイスの実装はPhoneWindowManager.javaクラスにあるため、この時点でPhoneWindowManager.javaのfinishedGoingToSleep()メソッドに転送されます。

    // Called on the PowerManager's Notifier thread.
    @Override
    public void finishedGoingToSleep(int why) {
        EventLog.writeEvent(70000, 0);
        if (DEBUG_WAKEUP) Slog.i(TAG, "Finished going to sleep... (why=" + why + ")");
        MetricsLogger.histogram(mContext, "screen_timeout", mLockScreenTimeout / 1000);

        // We must get this work done here because the power manager will drop
        // the wake lock and let the system suspend once this function returns.
        synchronized (mLock) {
            mAwake = false;
            updateWakeGestureListenerLp();
            updateOrientationListenerLp();
            updateLockScreenTimeout();
        }
        if (mKeyguardDelegate != null) {
            mKeyguardDelegate.onFinishedGoingToSleep(why);
        }
    }
このメソッドを分析して、この文を確認します。

mKeyguardDelegate.onFinishedGoingToSleep(why);
つまり、KeyguardServiceDelegate.javaのonFinishedGoingToSleep()メソッドが呼び出されます。上記の分析プロセスでは、PhoneWindowManager.javaがmKeyguardDelegateオブジェクト(KeyguardServiceDelegate.java)を介してKeyguardViewMediator.javaを有効にし、メソッドを呼び出すことがわかっています。 ;つまり、この時点で、この文のロジックはKeyguardViewMediator.javaクラスのonFinishedGoingToSleep()メソッドに転送されています。

    public void onFinishedGoingToSleep(int why) {
        if (DEBUG) Log.d(TAG, "onFinishedGoingToSleep(" + why + ")");
        synchronized (this) {
            mDeviceInteractive = false;
            mGoingToSleep = false;

            resetKeyguardDonePendingLocked();
            mHideAnimationRun = false;

            notifyFinishedGoingToSleep();

            if (mPendingReset) {
                resetStateLocked();
                mPendingReset = false;
            }
            if (mPendingLock) {
                doKeyguardLocked(null);
                mPendingLock = false;
            }
        }
        KeyguardUpdateMonitor.getInstance(mContext).dispatchFinishedGoingToSleep(why);
    }

このメソッドでは、notifyFinishedGoingToSleep()メソッドを呼び出して、メッセージをNOTIFY_FINISHED_GOING_TO_SLEEPとしてmHandlerに送信します。

    private void notifyFinishedGoingToSleep() {
        if (DEBUG) Log.d(TAG, "notifyFinishedGoingToSleep");
        mHandler.sendEmptyMessage(NOTIFY_FINISHED_GOING_TO_SLEEP);
    }
mHandlerはこのメッセージを受信した後、handleNotifyFinishedGoingToSleep()メソッドを呼び出します。

case NOTIFY_FINISHED_GOING_TO_SLEEP:
    handleNotifyFinishedGoingToSleep();
    break;
このメソッドでは、StatusBarKeyguardViewManager.javaのonFinishedGoingToSleep()メソッドを呼び出します。

    private void handleNotifyFinishedGoingToSleep() {
        synchronized (KeyguardViewMediator.this) {
            if (DEBUG) Log.d(TAG, "handleNotifyFinishedGoingToSleep");
            mStatusBarKeyguardViewManager.onFinishedGoingToSleep();
        }
    }
StatusBarKeyguardViewManager.javaのonFinishedGoingToSleep()メソッドを見てみましょう。
    public void onFinishedGoingToSleep() {
        mDeviceInteractive = false;
        mPhoneStatusBar.onFinishedGoingToSleep();
        mBouncer.onScreenTurnedOff();
    }
1. PhoneStatusBar.javaのonFinishedGoingToSleep()を呼び出して、PhoneStatusBarに現在のステータスを更新するよう通知します。2。KeyguardBouncer.java
のonScreenTurnedOff()メソッドを入力して、実際にキーガードのロードを開始します。


次に、KeyguardBouncer.javaのonScreenTurnedOff()メソッドを見てください。

    public void onScreenTurnedOff() {
        if (mKeyguardView != null && mRoot != null && mRoot.getVisibility() == View.VISIBLE) {
            mKeyguardView.onPause();
        }
    }
KeyguardHostView.javaのonPause()メソッドを呼び出します。
    /**
     * Called when the Keyguard is not actively shown anymore on the screen.
     */
    public void onPause() {
        if (DEBUG) Log.d(TAG, String.format("screen off, instance %s at %s",
                Integer.toHexString(hashCode()), SystemClock.uptimeMillis()));
        mSecurityContainer.showPrimarySecurityScreen(true);
        mSecurityContainer.onPause();
        clearFocus();
    }
KeyguardSecurityContainer.javaのshowPrimarySecurityScreen()メソッドを引き続き呼び出します。上記の分析によると、最初に現在のロック画面メソッドを取得し、次に取得したロック画面メソッドに従ってロック画面インターフェイスをロードすることがわかっています。
これで完了です。 画面オフ状態のキーガード読み込みプロセス分析。


画面が正常にオフになっている場合のキーガードプロセスの概要:
1。電源ボタンを押すか、自動的に画面をオフにするかにかかわらず、PowerManagerService.javaのgotoSleep()メソッドに対して実行されます
。2。このメソッドでは、一連の呼び出しを通じてPhoneWindowManager.javaに転送されます。FinishedGoingToSleep()メソッド;
3. PhoneWindowManager.javaクラスで、KeyguardServiceDelegate.javaクラスのオブジェクトmKeyguardDelegateを介してKeyguardViewMediator.javaを有効にします;
4。スケジューラとしてKeyguardViewMediator.javaキーガードのロードをここから開始します
。5。最後に、KeyguardSecurityContainer.javaのshowPrimarySecurityScreen()メソッドのロック画面メソッドに従ってロック画面インターフェイスをロードします。


























おすすめ

転載: blog.csdn.net/Otaku_627/article/details/53769473