安卓锁屏相关流程
安卓锁屏相关流程
时间:2022-01-04
流程:PIN码解锁流程
PIN码解锁的View是KeyguardPINView,此类的父类是KeyguardPinBasedInputView,KeyguardPinBasedInputView这个类继承于KeyguardAbsKeyInputView。
1、当在PIN码解锁页面按下OK或者确定按钮时
mOkButton = findViewById(R.id.key_enter);
if (mOkButton != null) {
mOkButton.setOnTouchListener(this);
mOkButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mPasswordEntry.isEnabled()) {
verifyPasswordAndUnlock();
}
}
});
mOkButton.setOnHoverListener(new LiftToActivateListener(getContext()));
}
2、触发检测密码 verifyPasswordAndUnlock(),这个方法中,实例化了LockPatternChecker.checkCredential,其中提供了2个回调接口,其中onEarlyMatched()处理验证成功,onChecked处理验证失败。
mPendingLockCheck = LockPatternChecker.checkCredential(
mLockPatternUtils,
password,
userId,
new LockPatternChecker.OnCheckCallback() {
@Override
public void onEarlyMatched() {
if (LatencyTracker.isEnabled(mContext)) {
LatencyTracker.getInstance(mContext).onActionEnd(
ACTION_CHECK_CREDENTIAL);
}
onPasswordChecked(userId, true /* matched */, 0 /* timeoutMs */,
true /* isValidPassword */);
password.zeroize();
}
@Override
public void onChecked(boolean matched, int timeoutMs) {
if (LatencyTracker.isEnabled(mContext)) {
LatencyTracker.getInstance(mContext).onActionEnd(
ACTION_CHECK_CREDENTIAL_UNLOCKED);
}
setPasswordEntryInputEnabled(true);
mPendingLockCheck = null;
if (!matched) {
onPasswordChecked(userId, false /* matched */, timeoutMs,
true /* isValidPassword */);
}
password.zeroize();
}
@Override
public void onCancelled() {
// We already got dismissed with the early matched callback, so we cancelled
// the check. However, we still need to note down the latency.
if (LatencyTracker.isEnabled(mContext)) {
LatencyTracker.getInstance(mContext).onActionEnd(
ACTION_CHECK_CREDENTIAL_UNLOCKED);
}
password.zeroize();
}
});
}
3、验证时,调用KeyguardAbsKeyInputView.onPasswordChecked()方法。检查密码正确后,利用dismiss去掉界面。
private void onPasswordChecked(int userId, boolean matched, int timeoutMs,
boolean isValidPassword) {
boolean dismissKeyguard = KeyguardUpdateMonitor.getCurrentUser() == userId;
if (matched) {
mCallback.reportUnlockAttempt(userId, true, 0);
if (dismissKeyguard) {
mDismissing = true;
mCallback.dismiss(true, userId);
}
} else {
if (isValidPassword) {
mCallback.reportUnlockAttempt(userId, false, timeoutMs);
if (timeoutMs > 0) {
long deadline = mLockPatternUtils.setLockoutAttemptDeadline(
userId, timeoutMs);
handleAttemptLockout(deadline);
}
}
if (timeoutMs == 0) {
mSecurityMessageDisplay.setMessage(getWrongPasswordStringId());
}
}
resetPasswordText(true /* animate */, !matched /* announce deletion if no match */);
}
4、在KeyguardHostView.java中实现dismiss方法
/**
* Dismisses the keyguard by going to the next screen or making it gone.
* @param targetUserId a user that needs to be the foreground user at the dismissal completion.
* @return True if the keyguard is done.
*/
public boolean dismiss(int targetUserId) {
return dismiss(false, targetUserId, false);
}
5、调用 mSecurityContainer也就是KeyguardSecurityContainer里面的 showNextSecurityScreenOrFinish的方法去finish
@Override
public boolean dismiss(boolean authenticated, int targetUserId,
boolean bypassSecondaryLockScreen) {
return mSecurityContainer.showNextSecurityScreenOrFinish(authenticated, targetUserId,
bypassSecondaryLockScreen);
}
6、获取当前的view进行finish,如sim pin view,pin码view,password view等
boolean showNextSecurityScreenOrFinish(boolean authenticated, int targetUserId,
boolean bypassSecondaryLockScreen) {
if (DEBUG) Log.d(TAG, "showNextSecurityScreenOrFinish(" + authenticated + ")");
boolean finish = false;
boolean strongAuth = false;
int eventSubtype = -1;
BouncerUiEvent uiEvent = BouncerUiEvent.UNKNOWN;
if (mUpdateMonitor.getUserHasTrust(targetUserId)) {
finish = true;
eventSubtype = BOUNCER_DISMISS_EXTENDED_ACCESS;
uiEvent = BouncerUiEvent.BOUNCER_DISMISS_EXTENDED_ACCESS;
} else if (mUpdateMonitor.getUserUnlockedWithBiometric(targetUserId)) {
finish = true;
eventSubtype = BOUNCER_DISMISS_BIOMETRIC;
uiEvent = BouncerUiEvent.BOUNCER_DISMISS_BIOMETRIC;
} else if (SecurityMode.None == mCurrentSecuritySelection) {
SecurityMode securityMode = mSecurityModel.getSecurityMode(targetUserId);
if (SecurityMode.None == securityMode) {
finish = true; // no security required
eventSubtype = BOUNCER_DISMISS_NONE_SECURITY;
uiEvent = BouncerUiEvent.BOUNCER_DISMISS_NONE_SECURITY;
} else {
showSecurityScreen(securityMode); // switch to the alternate security view
}
} else if (authenticated) {
switch (mCurrentSecuritySelection) {
case Pattern:
case Password:
case PIN:
strongAuth = true;
finish = true;
eventSubtype = BOUNCER_DISMISS_PASSWORD;
uiEvent = BouncerUiEvent.BOUNCER_DISMISS_PASSWORD;
break;
case SimPin:
case SimPuk:
// Shortcut for SIM PIN/PUK to go to directly to user's security screen or home
SecurityMode securityMode = mSecurityModel.getSecurityMode(targetUserId);
if (securityMode == SecurityMode.None && mLockPatternUtils.isLockScreenDisabled(
KeyguardUpdateMonitor.getCurrentUser())) {
finish = true;
eventSubtype = BOUNCER_DISMISS_SIM;
uiEvent = BouncerUiEvent.BOUNCER_DISMISS_SIM;
} else {
showSecurityScreen(securityMode);
}
break;
default:
Log.v(TAG, "Bad security screen " + mCurrentSecuritySelection + ", fail safe");
showPrimarySecurityScreen(false);
break;
}
}
// Check for device admin specified additional security measures.
if (finish && !bypassSecondaryLockScreen) {
Intent secondaryLockscreenIntent =
mUpdateMonitor.getSecondaryLockscreenRequirement(targetUserId);
if (secondaryLockscreenIntent != null) {
mSecondaryLockScreenController.show(secondaryLockscreenIntent);
return false;
}
}
if (eventSubtype != -1) {
mMetricsLogger.write(new LogMaker(MetricsEvent.BOUNCER)
.setType(MetricsEvent.TYPE_DISMISS).setSubtype(eventSubtype));
}
if (uiEvent != BouncerUiEvent.UNKNOWN) {
sUiEventLogger.log(uiEvent);
}
if (finish) {
mSecurityCallback.finish(strongAuth, targetUserId);
}
return finish;
}
7、解锁验证已经成功,需要回调 keyguardDone dismiss keyguard
@Override
public void finish(boolean strongAuth, int targetUserId) {
// If there's a pending runnable because the user interacted with a widget
// and we're leaving keyguard, then run it.
boolean deferKeyguardDone = false;
if (mDismissAction != null) {
deferKeyguardDone = mDismissAction.onDismiss();
mDismissAction = null;
mCancelAction = null;
}
if (mViewMediatorCallback != null) {
if (deferKeyguardDone) {
mViewMediatorCallback.keyguardDonePending(strongAuth, targetUserId);
} else {
mViewMediatorCallback.keyguardDone(strongAuth, targetUserId);
}
}
}
8、在KeyguardViewMediator.java实现该keyguardDone
@Override
public void keyguardDone(boolean strongAuth, int targetUserId) {
if (targetUserId != ActivityManager.getCurrentUser()) {
return;
}
if (DEBUG) Log.d(TAG, "keyguardDone");
tryKeyguardDone();
}
9、执行KeyguardViewMediator中的tryKeyguardDone
private void tryKeyguardDone() {
if (DEBUG) {
Log.d(TAG, "tryKeyguardDone: pending - " + mKeyguardDonePending + ", animRan - "
+ mHideAnimationRun + " animRunning - " + mHideAnimationRunning);
}
if (!mKeyguardDonePending && mHideAnimationRun && !mHideAnimationRunning) {
handleKeyguardDone();
} else if (!mHideAnimationRun) {
if (DEBUG) Log.d(TAG, "tryKeyguardDone: starting pre-hide animation");
mHideAnimationRun = true;
mHideAnimationRunning = true;
mKeyguardViewControllerLazy.get()
.startPreHideAnimation(mHideAnimationFinishedRunnable);
}
}
10、执行handleKeyguardDone()
private void handleKeyguardDone() {
Trace.beginSection("KeyguardViewMediator#handleKeyguardDone");
final int currentUser = KeyguardUpdateMonitor.getCurrentUser();
mUiBgExecutor.execute(() -> {
if (mLockPatternUtils.isSecure(currentUser)) {
mLockPatternUtils.getDevicePolicyManager().reportKeyguardDismissed(currentUser);
}
});
if (DEBUG) Log.d(TAG, "handleKeyguardDone");
synchronized (this) {
resetKeyguardDonePendingLocked();
}
if (mGoingToSleep) {
mUpdateMonitor.clearBiometricRecognized();
Log.i(TAG, "Device is going to sleep, aborting keyguardDone");
return;
}
if (mExitSecureCallback != null) {
try {
mExitSecureCallback.onKeyguardExitResult(true /* authenciated */);
} catch (RemoteException e) {
Slog.w(TAG, "Failed to call onKeyguardExitResult()", e);
}
mExitSecureCallback = null;
// after succesfully exiting securely, no need to reshow
// the keyguard when they've released the lock
mExternallyEnabled = true;
mNeedToReshowWhenReenabled = false;
updateInputRestricted();
}
handleHide();
mUpdateMonitor.clearBiometricRecognized();
Trace.endSection();
}
11、执行当前的handleHide
private void handleHide() {
Trace.beginSection("KeyguardViewMediator#handleHide");
// It's possible that the device was unlocked in a dream state. It's time to wake up.
if (mAodShowing) {
PowerManager pm = mContext.getSystemService(PowerManager.class);
pm.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_GESTURE,
"com.android.systemui:BOUNCER_DOZING");
}
synchronized (KeyguardViewMediator.this) {
if (DEBUG) Log.d(TAG, "handleHide");
if (mustNotUnlockCurrentUser()) {
// In split system user mode, we never unlock system user. The end user has to
// switch to another user.
// TODO: We should stop it early by disabling the swipe up flow. Right now swipe up
// still completes and makes the screen blank.
if (DEBUG) Log.d(TAG, "Split system user, quit unlocking.");
return;
}
mHiding = true;
if (mShowing && !mOccluded) {
mKeyguardGoingAwayRunnable.run();
} else {
handleStartKeyguardExitAnimation(
SystemClock.uptimeMillis() + mHideAnimation.getStartOffset(),
mHideAnimation.getDuration());
}
}
Trace.endSection();
}
时间:2022-01-05
12、默认mShowing && !mOccluded条件成立,锁屏显示且无遮挡,则执行mKeyguardGoingAwayRunnable.run();
private final Runnable mKeyguardGoingAwayRunnable = new Runnable() {
@Override
public void run() {
Trace.beginSection("KeyguardViewMediator.mKeyGuardGoingAwayRunnable");
if (DEBUG) Log.d(TAG, "keyguardGoingAway");
mKeyguardViewControllerLazy.get().keyguardGoingAway();
int flags = 0;
if (mKeyguardViewControllerLazy.get().shouldDisableWindowAnimationsForUnlock()
|| (mWakeAndUnlocking && !mPulsing)) {
flags |= WindowManagerPolicyConstants
.KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS;
}
if (mKeyguardViewControllerLazy.get().isGoingToNotificationShade()
|| (mWakeAndUnlocking && mPulsing)) {
flags |= WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_TO_SHADE;
}
if (mKeyguardViewControllerLazy.get().isUnlockWithWallpaper()) {
flags |= WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER;
}
if (mKeyguardViewControllerLazy.get().shouldSubtleWindowAnimationsForUnlock()) {
flags |= WindowManagerPolicyConstants
.KEYGUARD_GOING_AWAY_FLAG_SUBTLE_WINDOW_ANIMATIONS;
}
mUpdateMonitor.setKeyguardGoingAway(true);
mKeyguardViewControllerLazy.get().setKeyguardGoingAwayState(true);
// Don't actually hide the Keyguard at the moment, wait for window
// manager until it tells us it's safe to do so with
// startKeyguardExitAnimation.
// Posting to mUiOffloadThread to ensure that calls to ActivityTaskManager will be in
// order.
final int keyguardFlag = flags;
mUiBgExecutor.execute(() -> {
try {
ActivityTaskManager.getService().keyguardGoingAway(keyguardFlag);
} catch (RemoteException e) {
Log.e(TAG, "Error while calling WindowManager", e);
}
});
Trace.endSection();
}
};
13、keyguardGoingAway
frameworks/base/services/core/java/com/android/server/am/ActivityTaskManagerService.java
@Override
public void keyguardGoingAway(int flags) {
enforceNotIsolatedCaller("keyguardGoingAway");
final long token = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
mKeyguardController.keyguardGoingAway(flags);
}
} finally {
Binder.restoreCallingIdentity(token);
}
}
14、.keyguardGoingAway
frameworks/base/services/core/java/com/android/server/am/KeyguardController.java
void keyguardGoingAway(int flags) {
if (!mKeyguardShowing) {
return;
}
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "keyguardGoingAway");
mService.deferWindowLayout();
try {
setKeyguardGoingAway(true);
EventLogTags.writeWmSetKeyguardShown(
1 /* keyguardShowing */,
mAodShowing ? 1 : 0,
1 /* keyguardGoingAway */,
"keyguardGoingAway");
mRootWindowContainer.getDefaultDisplay().mDisplayContent
.prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY,
false /* alwaysKeepCurrent */, convertTransitFlags(flags),
false /* forceOverride */);
updateKeyguardSleepToken();
// Some stack visibility might change (e.g. docked stack)
mRootWindowContainer.resumeFocusedStacksTopActivities();
mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
mRootWindowContainer.addStartingWindowsForVisibleActivities();
mWindowManager.executeAppTransition();
} finally {
mService.continueWindowLayout();
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
}
15、executeAppTransition
frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
@Override
public void executeAppTransition() {
if (!checkCallingPermission(MANAGE_APP_TOKENS, "executeAppTransition()")) {
throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
}
getDefaultDisplayContentLocked().executeAppTransition();
}
16、getDefaultDisplayContentLocked().executeAppTransition();
base\services\core\java\com\android\server\wm\DisplayContent.java
void executeAppTransition() {
if (mAppTransition.isTransitionSet()) {
ProtoLog.w(WM_DEBUG_APP_TRANSITIONS,
"Execute app transition: %s, displayId: %d Callers=%s",
mAppTransition, mDisplayId, Debug.getCallers(5));
mAppTransition.setReady();
mWmService.mWindowPlacerLocked.requestTraversal();
}
}
17、 mWmService.mWindowPlacerLocked.requestTraversal();
windowSurfacePlacer.java
void requestTraversal() {
if (mTraversalScheduled) {
return;
}
// Set as scheduled even the request will be deferred because mDeferredRequests is also
// increased, then the end of deferring will perform the request.
mTraversalScheduled = true;
if (mDeferDepth > 0) {
mDeferredRequests++;
if (DEBUG) Slog.i(TAG, "Defer requestTraversal " + Debug.getCallers(3));
return;
}
mService.mAnimationHandler.post(mPerformSurfacePlacement);
}
18、performSurfacePlacement
final void performSurfacePlacement() {
performSurfacePlacement(false /* force */);
}
final void performSurfacePlacement(boolean force) {
if (mDeferDepth > 0 && !force) {
mDeferredRequests++;
return;
}
int loopCount = 6;
do {
mTraversalScheduled = false;
performSurfacePlacementLoop();
mService.mAnimationHandler.removeCallbacks(mPerformSurfacePlacement);
loopCount--;
} while (mTraversalScheduled && loopCount > 0);
mService.mRoot.mWallpaperActionPending = false;
}
private void performSurfacePlacementLoop() {
if (mInLayout) {
if (DEBUG) {
throw new RuntimeException("Recursive call!");
}
Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout. Callers="
+ Debug.getCallers(3));
return;
}
// TODO(multi-display):
final DisplayContent defaultDisplay = mService.getDefaultDisplayContentLocked();
if (defaultDisplay.mWaitingForConfig) {
// Our configuration has changed (most likely rotation), but we
// don't yet have the complete configuration to report to
// applications. Don't do any window layout until we have it.
return;
}
if (!mService.mDisplayReady) {
// Not yet initialized, nothing to do.
return;
}
mInLayout = true;
if (!mService.mForceRemoves.isEmpty()) {
// Wait a little bit for things to settle down, and off we go.
while (!mService.mForceRemoves.isEmpty()) {
final WindowState ws = mService.mForceRemoves.remove(0);
Slog.i(TAG, "Force removing: " + ws);
ws.removeImmediately();
}
Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
Object tmp = new Object();
synchronized (tmp) {
try {
tmp.wait(250);
} catch (InterruptedException e) {
}
}
}
try {
mService.mRoot.performSurfacePlacement();
mInLayout = false;
if (mService.mRoot.isLayoutNeeded()) {
if (++mLayoutRepeatCount < 6) {
requestTraversal();
} else {
Slog.e(TAG, "Performed 6 layouts in a row. Skipping");
mLayoutRepeatCount = 0;
}
} else {
mLayoutRepeatCount = 0;
}
if (mService.mWindowsChanged && !mService.mWindowChangeListeners.isEmpty()) {
mService.mH.removeMessages(REPORT_WINDOWS_CHANGE);
mService.mH.sendEmptyMessage(REPORT_WINDOWS_CHANGE);
}
} catch (RuntimeException e) {
mInLayout = false;
Slog.wtf(TAG, "Unhandled exception while laying out windows", e);
}
}
19、handleStartTransitionForKeyguardLw
PWM
private int handleStartTransitionForKeyguardLw(int transit, long duration) {
if (mKeyguardOccludedChanged) {
if (DEBUG_KEYGUARD) Slog.d(TAG, "transition/occluded changed occluded="
+ mPendingKeyguardOccluded);
mKeyguardOccludedChanged = false;
if (setKeyguardOccludedLw(mPendingKeyguardOccluded, false /* force */)) {
return FINISH_LAYOUT_REDO_LAYOUT | FINISH_LAYOUT_REDO_WALLPAPER;
}
}
if (AppTransition.isKeyguardGoingAwayTransit(transit)) {
if (DEBUG_KEYGUARD) Slog.d(TAG, "Starting keyguard exit animation");
startKeyguardExitAnimation(SystemClock.uptimeMillis(), duration);
}
return 0;
}
@Override
public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) {
if (mKeyguardDelegate != null) {
if (DEBUG_KEYGUARD) Slog.d(TAG, "PWM.startKeyguardExitAnimation");
mKeyguardDelegate.startKeyguardExitAnimation(startTime, fadeoutDuration);
}
}
22、startKeyguardExitAnimation
KeyguardServiceDelegate.java
public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) {
if (mKeyguardService != null) {
mKeyguardService.startKeyguardExitAnimation(startTime, fadeoutDuration);
}
}
KeyguardService.java
@Override
public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) {
Trace.beginSection("KeyguardService.mBinder#startKeyguardExitAnimation");
checkPermission();
mKeyguardViewMediator.startKeyguardExitAnimation(startTime, fadeoutDuration);
Trace.endSection();
}
KeyguardViewMediator.java
public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) {
Trace.beginSection("KeyguardViewMediator#startKeyguardExitAnimation");
Message msg = mHandler.obtainMessage(START_KEYGUARD_EXIT_ANIM,
new StartKeyguardExitAnimParams(startTime, fadeoutDuration));
mHandler.sendMessage(msg);
Trace.endSection();
}
23、执行此方法,发送消息START_KEYGUARD_EXIT_ANIM,此消息的执行逻辑如下
case START_KEYGUARD_EXIT_ANIM:
Trace.beginSection(
"KeyguardViewMediator#handleMessage START_KEYGUARD_EXIT_ANIM");
StartKeyguardExitAnimParams params = (StartKeyguardExitAnimParams) msg.obj;
handleStartKeyguardExitAnimation(params.startTime, params.fadeoutDuration);
mFalsingManager.onSuccessfulUnlock();
Trace.endSection();
break;
24、此时执行handleStartKeyguardExitAnimation方法
private void handleStartKeyguardExitAnimation(long startTime, long fadeoutDuration) {
Trace.beginSection("KeyguardViewMediator#handleStartKeyguardExitAnimation");
if (DEBUG) Log.d(TAG, "handleStartKeyguardExitAnimation startTime=" + startTime
+ " fadeoutDuration=" + fadeoutDuration);
synchronized (KeyguardViewMediator.this) {
if (!mHiding) {
// Tell ActivityManager that we canceled the keyguardExitAnimation.
setShowingLocked(mShowing, true /* force */);
return;
}
mHiding = false;
if (mWakeAndUnlocking && mDrawnCallback != null) {
// Hack level over 9000: To speed up wake-and-unlock sequence, force it to report
// the next draw from here so we don't have to wait for window manager to signal
// this to our ViewRootImpl.
mKeyguardViewControllerLazy.get().getViewRootImpl().setReportNextDraw();
notifyDrawn(mDrawnCallback);
mDrawnCallback = null;
}
// only play "unlock" noises if not on a call (since the incall UI
// disables the keyguard)
if (TelephonyManager.EXTRA_STATE_IDLE.equals(mPhoneState)) {
playSounds(false);
}
setShowingLocked(false);
mWakeAndUnlocking = false;
mDismissCallbackRegistry.notifyDismissSucceeded();
mKeyguardViewControllerLazy.get().hide(startTime, fadeoutDuration);
resetKeyguardDonePendingLocked();
mHideAnimationRun = false;
adjustStatusBarLocked();
sendUserPresentBroadcast();
}
Trace.endSection();
}
25、mKeyguardViewControllerLazy.get().hide(startTime, fadeoutDuration);
执行StatusBarKeyguardViewManager.hide()方法,隐藏锁屏
adjustStatusBarLocked(); 更新StatusBarLocked的状态为false
sendUserPresentBroadcast();发送解锁成功的广播。
最后附上时序图 。仅供参考!!! 部分详细时序未画出!!!
时序图不是很清楚 附上时序图网址以及生成代码
title PIN解锁
KeyguardPinBasedInputView->+KeyguardAbsKeyInputView: verifyPasswordAndUnlock();
KeyguardAbsKeyInputView->-KeyguardAbsKeyInputView:onPasswordChecked()
KeyguardAbsKeyInputView->+KeyguardHostView:dismiss()
KeyguardHostView->-KeyguardHostView:dismiss()
KeyguardHostView->+KeyguardSecurityContainer:showNextSecurityScreenOrFinish()
KeyguardSecurityContainer->-KeyguardHostView:finish()
KeyguardHostView->+KeyguardViewMediator:keyguardDone()
KeyguardViewMediator->+KeyguardViewMediator:tryKeyguardDone()
KeyguardViewMediator->+KeyguardViewMediator:handleKeyguardDone()
KeyguardViewMediator->-KeyguardViewMediator:handleHide()
KeyguardViewMediator->+PhoneWindowManager:mKeyguardGoingAwayRunnable.run()
KeyguardViewMediator->StatusBarKeyguardViewManager:keyguardGoinfAway()
PhoneWindowManager->-PhoneWindowManager:startKeyguardExitAnimation()
PhoneWindowManager->+KeyguardServiceDelegate:startKeyguardExitAnimation()
KeyguardServiceDelegate->-KeyguardService:startKeyguardExitAnimation()
KeyguardService->KeyguardViewMediator:startKeyguardExitAnimation()
KeyguardViewMediator->+KeyguardViewMediator:handleStartKeyguardExitAnimation
KeyguardViewMediator->-StatusBarKeyguardViewManager:hide()
KeyguardViewMediator->StatusBarManager:adjustStatusBarLocked()
KeyguardViewMediator->KeyguardServiceDelegate:sendUserPresentBroadcast
更多推荐
所有评论(0)