解锁流程log:
08-22 04:42:31.508 3194 3194 I chensenquan: =========verifyPasswordAndUnlock=======
08-22 04:42:31.810 3194 3194 I chensenquan: verifyPasswordAndUnlock onEarlyMatched
08-22 04:42:31.810 3194 3194 I chensenquan: ===verifyPasswordAndUnlock====true,dismissKeyguard=true,isValidPassword=true,timeoutMs=0
08-22 04:42:31.824 3194 3194 D chensenquan: showNext.. mCurrentSecuritySelection = PIN
08-22 04:42:31.832 3194 3194 D chensenquan: KeyguardHostView.finish mViewMediatorCallback not null deferKeyguardDone=false
08-22 04:42:31.834 3194 3194 D chensenquan: KeyguardViewMediator.tryKeyguardDone startPreHideAnimation(mHideAnimationFinishedRunnable)
08-22 04:42:31.834 3194 3194 D chensenquan: KeyguardBouncer.startPreHideAnimation mKeyguardView=com.android.keyguard.KeyguardHostView{e6c40fc V.E...... ........ 0,84-480,759 #7f0a0148 app:id/keyguard_host_view} runnable=com.android.systemui.keyguard.-$Lambda$sJEWzSUgVYHCfk83FvvFNEzkKS4@f3e6c9a
08-22 04:42:31.835 3194 3194 D chensenquan: KeyguardSecurityContainer.startDisappearAnimation mCurrentSecuritySelection=PIN
08-22 04:42:31.837 3194 3194 D chensenquan: KeyguardViewMediator.tryKeyguardDone
08-22 04:42:31.838 3194 3194 D chensenquan1: handleKeyguardDone===========
08-22 04:42:31.841 3194 3194 D chensenquan: KeyguardViewMediator.handleKeyguardDone
08-22 04:42:31.841 3194 3194 D chensenquan: KeyguardViewMediator.handleHide mShowing=true, mOccluded=false
08-22 04:42:31.842 3194 3194 I chensenquan: ======setKeyguardGoingAway======
08-22 04:42:31.842 3194 3194 I chensenquan: ======keyguardGoingAway======
08-22 04:42:32.007 3194 3194 I chensenquan: ======keyguardGoingAway===flags===
08-22 04:42:32.017 3194 3194 I chensenquan: verifyPasswordAndUnlock onChecked
08-22 04:42:32.657 3194 3507 D chensenquan: KeyguardService.startKeyguardExitAnimation startTime=267700, fadeoutDuration=150
08-22 04:42:32.657 3194 3507 I chensenquan1: =======startKeyguardExitAnimation======
08-22 04:42:32.658 3194 3194 D chensenquan: KeyguardViewMediator.mHandler START_KEYGUARD_EXIT_ANIM
08-22 04:42:32.658 3194 3194 I chensenquan1: ======handleStartKeyguardExitAnimation======
08-22 04:42:32.659 3194 3194 D chensenquan: KeyguardViewMediator.handleStartKeyguardExitAnimation mHiding=true, mWakeAndUnlocking=false, mShowing=true
08-22 04:42:32.659 3194 3194 D chensenquan: KeyguardViewMediator.handleStartKeyguardExitAnimation 11111
08-22 04:42:32.660 3194 3507 I chensenquan1: =======startKeyguardExitAnimation11======
08-22 04:42:32.667 3194 3194 D chensenquan: KeyguardViewMediator.handleStartKeyguardExitAnimation 222
08-22 04:42:32.753 3194 3194 D chensenquan: KeyguardViewMediator.handleStartKeyguardExitAnimation 333
1.点击ok按钮,开始解锁
verifyPasswordAndUnlock()
vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java
protected void verifyPasswordAndUnlock() {
Log.i("chensenquan", "=========verifyPasswordAndUnlock=======");
//[BUGFIX]Defect 5776584 2018.03.13
long currTime = System.currentTimeMillis();
Log.d("UiReactionTimeTest","Perform unlockscreen action from Swipe mode at " + currTime + " ms");
if (mDismissing) return; // already verified but haven't been dismissed; don't do it again.
final String entry = getPasswordText();
setPasswordEntryInputEnabled(false);
if (mPendingLockCheck != null) {
mPendingLockCheck.cancel(false);
}
final int userId = KeyguardUpdateMonitor.getCurrentUser();
if (entry.length() <= MINIMUM_PASSWORD_LENGTH_BEFORE_REPORT) {
// to avoid accidental lockout, only count attempts that are long enough to be a
// real password. This may require some tweaking.
setPasswordEntryInputEnabled(true);
Log.i("chensenquan", "verifyPasswordAndUnlock onPasswordChecked");
onPasswordChecked(userId, false /* matched */, 0, false /* not valid - too short */);
return;
}
if (LatencyTracker.isEnabled(mContext)) {
LatencyTracker.getInstance(mContext).onActionStart(ACTION_CHECK_CREDENTIAL);
LatencyTracker.getInstance(mContext).onActionStart(ACTION_CHECK_CREDENTIAL_UNLOCKED);
}
mPendingLockCheck = LockPatternChecker.checkPassword(//检查密码,然后回调
mLockPatternUtils,
entry,
userId,
new LockPatternChecker.OnCheckCallback() {
@Override
public void onEarlyMatched() {//密码正确
if (LatencyTracker.isEnabled(mContext)) {
LatencyTracker.getInstance(mContext).onActionEnd(
ACTION_CHECK_CREDENTIAL);
}
Log.i("chensenquan", "verifyPasswordAndUnlock onEarlyMatched");
onPasswordChecked(userId, true /* matched */, 0 /* timeoutMs */,
true /* isValidPassword */);
}
@Override
public void onChecked(boolean matched, int timeoutMs) {
if (LatencyTracker.isEnabled(mContext)) {
LatencyTracker.getInstance(mContext).onActionEnd(
ACTION_CHECK_CREDENTIAL_UNLOCKED);
}
Log.i("chensenquan", "verifyPasswordAndUnlock onChecked");
setPasswordEntryInputEnabled(true);
mPendingLockCheck = null;
if (!matched) {
Log.i("chensenquan", "verifyPasswordAndUnlock matched"+matched);
onPasswordChecked(userId, false /* matched */, timeoutMs,
true /* isValidPassword */);
}
}
@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);
}
}
});
}
2.检查密码正确后,利用dismiss去掉界面
private void onPasswordChecked(int userId, boolean matched, int timeoutMs,
boolean isValidPassword) {
boolean dismissKeyguard = KeyguardUpdateMonitor.getCurrentUser() == userId;
Log.i("chensenquan", "===verifyPasswordAndUnlock===="+matched+",dismissKeyguard="
+dismissKeyguard+",isValidPassword="+isValidPassword+",timeoutMs="+timeoutMs);
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 */);
}
3.在KeyguardHostView.java中实现dismiss方法
vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/keyguard/KeyguardHostView.java
/**
* 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) {
/// M: If dm lock is on, should not let user by pass lockscreen
if (!AntiTheftManager.isDismissable()) {
return false;
}
return dismiss(false, targetUserId);
}
4.调用 mSecurityContainer里面的 showNextSecurityScreenOrFinish的方法去finish
@Override
public boolean dismiss(boolean authenticated, int targetUserId) {
return mSecurityContainer.showNextSecurityScreenOrFinish(authenticated, targetUserId);
}
5.获取当前的view进行finish,如sim pin view,pin码view,password view等
showNextSecurityScreenOrFinish vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
/**
* Shows the next security screen if there is one.
* @param authenticated true if the user entered the correct authentication
* @param targetUserId a user that needs to be the foreground user at the finish (if called)
* completion.
* @return true if keyguard is done
*/
boolean showNextSecurityScreenOrFinish(boolean authenticated, int targetUserId) {
if (DEBUG) Log.d(TAG, "showNextSecurityScreenOrFinish(" + authenticated + ")");
Log.d(TAG, "showNext.. mCurrentSecuritySelection = " + mCurrentSecuritySelection);
Log.d("chensenquan", "showNext.. mCurrentSecuritySelection = " + mCurrentSecuritySelection);
boolean finish = false;
boolean strongAuth = false;
if (mUpdateMonitor.getUserCanSkipBouncer(targetUserId)) {
finish = true;
} else if (SecurityMode.None == mCurrentSecuritySelection) {
SecurityMode securityMode = mSecurityModel.getSecurityMode(targetUserId);
if (SecurityMode.None == securityMode) {
if (DEBUG) {
Log.d(TAG, "showNextSecurityScreenOrFinish() " +
"- securityMode is None, just finish.");
}
finish = true; // no security required
} else {
if (DEBUG) {
Log.d(TAG, "showNextSecurityScreenOrFinish()" +
"- switch to the alternate security view for None mode.");
}
showSecurityScreen(securityMode); // switch to the alternate security view
}
} else if (authenticated) {
if (DEBUG) {
Log.d(TAG, "showNextSecurityScreenOrFinish() - authenticated is True," +
" and mCurrentSecuritySelection = " + mCurrentSecuritySelection);
}
// Shortcut for SIM PIN/PUK to go to directly to user's security screen or home
SecurityMode securityMode = mSecurityModel.getSecurityMode(
KeyguardUpdateMonitor.getCurrentUser());
if (DEBUG) {
Log.v(TAG, "securityMode = " + securityMode);
}
Log.d(TAG, "mCurrentSecuritySelection: " + mCurrentSecuritySelection);
switch (mCurrentSecuritySelection) {
case Pattern:
case Password:
case PIN:
strongAuth = true;
finish = true;
break;
// case SimPin:
// case SimPuk:
case SimPinPukMe1:
case SimPinPukMe2:
case SimPinPukMe3:
case SimPinPukMe4:
// 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) {
showSecurityScreen(securityMode);
} else {
finish = true;
}
break;
///M: ALPS01772213 for handling antitheft mode.
case AntiTheft:
SecurityMode nextMode = mSecurityModel.getSecurityMode(
KeyguardUpdateMonitor.getCurrentUser());
if (DEBUG) {
Log.v(TAG, "now is Antitheft, next securityMode = " + nextMode);
}
if (nextMode != SecurityMode.None) {
showSecurityScreen(nextMode);
} else {
finish = true;
}
break;
case RemoteSmartLock:
nextMode = mSecurityModel.getSecurityMode(
KeyguardUpdateMonitor.getCurrentUser());
Log.d(TAG, "TAG, current is RemoteSmartLock, next = " + nextMode);
if (nextMode != SecurityMode.None) {
showSecurityScreen(nextMode);
} else {
finish = true;
}
break;
default:
Log.v(TAG, "Bad security screen " + mCurrentSecuritySelection + ", fail safe");
showPrimarySecurityScreen(false);
break;
}
}
mSecurityCallback.updateNavbarStatus();
if (finish) {
mSecurityCallback.finish(strongAuth, targetUserId);
Log.d(TAG, "finish ");
}
if (DEBUG) Log.d(TAG, "showNextSecurityScreenOrFinish() - return finish = " + finish) ;
return finish;
}
6.解锁验证已经成功,需要回调 keyguardDone dismiss keyguard
vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/keyguard/KeyguardHostView.java
/**
* Authentication has happened and it's time to dismiss keyguard. This function
* should clean up and inform KeyguardViewMediator.
*
* @param strongAuth whether the user has authenticated with strong authentication like
* pattern, password or PIN but not by trust agents or fingerprint
* @param targetUserId a user that needs to be the foreground user at the dismissal completion.
*/
@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;
Log.d("chensenquan", "KeyguardHostView.finish deferKeyguardDone=" + deferKeyguardDone);
} else if (VoiceWakeupManagerProxy.getInstance().isDismissAndLaunchApp()) {
if (DEBUG) Log.d(TAG, "finish() - call VoiceWakeupManager.getInstance().onDismiss().");
VoiceWakeupManagerProxy.getInstance().onDismiss();
//we need to launch app & dismiss keyguard immediately
deferKeyguardDone = false;
// since we need to dismiss keyguard directly, skip onDismiss() of
// current security view.
// mDismissAction = null;
}
if (mViewMediatorCallback != null) {
Log.d("chensenquan", "KeyguardHostView.finish mViewMediatorCallback
not null deferKeyguardDone=" + deferKeyguardDone);
if (deferKeyguardDone) {
mViewMediatorCallback.keyguardDonePending(strongAuth, targetUserId);
} else {
mViewMediatorCallback.keyguardDone(strongAuth, targetUserId);
}
}
}
7.在KeyguardViewMediator.java实现该keyguardDone
vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@Override
public void keyguardDone(boolean strongAuth, int targetUserId) {
if (targetUserId != ActivityManager.getCurrentUser()) {
return;
}
tryKeyguardDone();
}
8.dismiss时需要执行 startPreHideAnimation动画,优雅的退出
private void tryKeyguardDone() {
if (!mKeyguardDonePending && mHideAnimationRun && !mHideAnimationRunning) {
Log.d("chensenquan", "KeyguardViewMediator.tryKeyguardDone");
handleKeyguardDone();
} else if (!mHideAnimationRun) {
mHideAnimationRun = true;
mHideAnimationRunning = true;
Log.d("chensenquan", "KeyguardViewMediator.tryKeyguardDone startPreHideAnimation(mHideAnimationFinishedRunnable)");
mStatusBarKeyguardViewManager.startPreHideAnimation(mHideAnimationFinishedRunnable);
}
}
9.在dismiss keyguard之前开始执行startPreHideAnimation动画,已保证安全退出
vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
/**
* Starts the animation before we dismiss Keyguard, i.e. an disappearing animation on the
* security view of the bouncer.
*
* @param finishRunnable the runnable to be run after the animation finished, or {@code null} if
* no action should be run
*/
public void startPreHideAnimation(Runnable finishRunnable) {
if (mBouncer.isShowing()) {
mBouncer.startPreHideAnimation(finishRunnable);
} else if (finishRunnable != null) {
finishRunnable.run();
}
}
10.开始执行startPreHideAnimation动画
vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
/**
* See {@link StatusBarKeyguardViewManager#startPreHideAnimation}.
*/
public void startPreHideAnimation(Runnable runnable) {
Log.d("chensenquan", "KeyguardBouncer.startPreHideAnimation
mKeyguardView=" + mKeyguardView + " runnable=" + runnable);
if (mKeyguardView != null) {
// Added by lei.ye.hz for Task 5362432 on 2017/11/14 begin
if (mBouncerLockIcon != null) {
mBouncerLockIcon.setPreHideAnimationRunning(true);
mBouncerLockIcon.update();
}
// Added by lei.ye.hz for Task 5362432 on 2017/11/14 end
mKeyguardView.startDisappearAnimation(runnable);
} else if (runnable != null) {
runnable.run();
}
}
11.执行startDisappearAnimation时是否完成,如果没有完成继续finishRunnable.run();
vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/keyguard/KeyguardHostView.java
public void startDisappearAnimation(Runnable finishRunnable) {
if (!mSecurityContainer.startDisappearAnimation(finishRunnable) && finishRunnable != null) {
finishRunnable.run();
}
}
12.根据不同解锁方式的view调用startDisappearAnimation方法
vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
public boolean startDisappearAnimation(Runnable onFinishRunnable) {
Log.d("chensenquan", "KeyguardSecurityContainer.startDisappearAnimation mCurrentSecuritySelection=" + mCurrentSecuritySelection);
if (mCurrentSecuritySelection != SecurityMode.None) {
return getSecurityView(mCurrentSecuritySelection).startDisappearAnimation(
onFinishRunnable);
}
return false;
}
13.动画startDisappearAnimation实现,注释的部分是去掉动画,并没有什么影响,可以节省解锁时间
mediatek/proprietary/packages/apps/SystemUI/src/com/android/keyguard/KeyguardPINView.java
@Override
public boolean startDisappearAnimation(final Runnable finishRunnable) {
enableClipping(false);
setTranslationY(0);
// AppearAnimationUtils.startTranslationYAnimation(this, 0 /* delay */, 280 /* duration */,
// mDisappearYTranslation, mDisappearAnimationUtils.getInterpolator());
// DisappearAnimationUtils disappearAnimationUtils = mKeyguardUpdateMonitor
// .needsSlowUnlockTransition()
// ? mDisappearAnimationUtilsLocked
// : mDisappearAnimationUtils;
// disappearAnimationUtils.startAnimation2d(mViews,
// new Runnable() {
// @Override
// public void run() {
// enableClipping(true);
// if (finishRunnable != null) {
// finishRunnable.run();
// }
// }
// });
enableClipping(true);
if (finishRunnable != null) {
finishRunnable.run();
}
return true;
}
14.执行完之后会回调finishRunnable → mHideAnimationFinishedRunnable
vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
private final Runnable mHideAnimationFinishedRunnable = () -> {
mHideAnimationRunning = false;
tryKeyguardDone();
};
15.处理dismiss keyguard
private void tryKeyguardDone() {
if (!mKeyguardDonePending && mHideAnimationRun && !mHideAnimationRunning) {
Log.d("chensenquan", "KeyguardViewMediator.tryKeyguardDone");
handleKeyguardDone();
} else if (!mHideAnimationRun) {
mHideAnimationRun = true;
mHideAnimationRunning = true;
Log.d("chensenquan", "KeyguardViewMediator.tryKeyguardDone startPreHideAnimation(mHideAnimationFinishedRunnable)");
mStatusBarKeyguardViewManager.startPreHideAnimation(mHideAnimationFinishedRunnable);
}
}
16.handleKeyguardDone
private void handleKeyguardDone() {
Trace.beginSection("KeyguardViewMediator#handleKeyguardDone");
final int currentUser = KeyguardUpdateMonitor.getCurrentUser();
mUiOffloadThread.submit(() -> {
if (mLockPatternUtils.isSecure(currentUser)) {
mLockPatternUtils.getDevicePolicyManager().reportKeyguardDismissed(currentUser);
}
});
synchronized (this) {
resetKeyguardDonePendingLocked();
}
///M: [ALPS01567248] Timing issue.
/// Voice Unlock View dismiss -> AntiTheft View shows
/// -> previous Voice Unlock dismiss flow calls handleKeyguardDone
/// -> remove AntiTheft View
/// So we avoid handleKeyguardDone if AntiTheft is the current view,
/// and not yet unlock correctly.
if (AntiTheftManager.isAntiTheftLocked()) {
Log.d(TAG, "handleKeyguardDone() - Skip keyguard done! antitheft = true" +
" or sim = " + mUpdateMonitor.isSimPinSecure());
return;
}
Log.d(TAG, "handleKeyguardDone before check remote lock");
if (RemoteLockManager.isRemoteLocked()) {
Log.d(TAG, "handleKeyguardDone() - Skip keyguard done! remoteLock = true" +
" or sim = " + mUpdateMonitor.isSimPinSecure());
return;
}
mKeyguardDoneOnGoing = true;
// Added by lei.ye.hz for Task 5362432 on 2017/11/17 begin
mUpdateMonitor.setKeyguardDoneOnGoing(true);
// Added by lei.ye.hz for Task 5362432 on 2017/11/17 end
mUpdateMonitor.clearFailedUnlockAttempts();
mUpdateMonitor.clearFingerprintRecognized();
// Added by lei.ye.hz for Task 5362432 on 2017/09/26 begin
mUpdateMonitor.clearTctFaceRecognized();
mUpdateMonitor.stopFaceUnlockIfNecessary();
// Added by lei.ye.hz for Task 5362432 on 2017/09/26 end
if (mGoingToSleep) {
Log.i(TAG, "Device is going to sleep, aborting keyguardDone");
// Added by lei.ye.hz for Task 5362432 on 2017/12/06 begin
// keyguard done is abort, therefore we need to clear this flag, otherwise face unlock cannot be restarted later
mUpdateMonitor.setKeyguardDoneOnGoing(false);
// Added by lei.ye.hz for Task 5362432 on 2017/12/06 end
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();
}
///M: [ALPS00827994] always to play sound for user to unlock keyguard
mSuppressNextLockSound = false;
Log.d("chensenquan", "KeyguardViewMediator.handleKeyguardDone");
handleHide();
Trace.endSection();
}
17.handleHide
private void handleHide() {
Trace.beginSection("KeyguardViewMediator#handleHide");
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;
}
Log.d("chensenquan", "KeyguardViewMediator.handleHide mShowing="
+ mShowing + ", mOccluded=" + mOccluded);
mHiding = true;
if (mShowing && !mOccluded) {
mKeyguardGoingAwayRunnable.run();
} else {
Log.d("chensenquan", "KeyguardViewMediator.handleHide
start handleStartKeyguardExitAnimation");
handleStartKeyguardExitAnimation(
SystemClock.uptimeMillis() + mHideAnimation.getStartOffset(),
mHideAnimation.getDuration());
}
}
Trace.endSection();
}
18.mKeyguardGoingAwayRunnable
private final Runnable mKeyguardGoingAwayRunnable = new Runnable() {
@Override
public void run() {
Trace.beginSection("KeyguardViewMediator.mKeyGuardGoingAwayRunnable");
if (DEBUG) Log.d(TAG, "keyguardGoingAway");
try {
mStatusBarKeyguardViewManager.keyguardGoingAway();
int flags = 0;
if (mStatusBarKeyguardViewManager.shouldDisableWindowAnimationsForUnlock()
|| mWakeAndUnlocking) {
flags |= WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS;
}
if (mStatusBarKeyguardViewManager.isGoingToNotificationShade()) {
flags |= WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_TO_SHADE;
}
if (mStatusBarKeyguardViewManager.isUnlockWithWallpaper()) {
flags |= WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER;
}
Log.i("chensenquan", "======setKeyguardGoingAway======");
mUpdateMonitor.setKeyguardGoingAway(true /* goingAway */);
// Don't actually hide the Keyguard at the moment, wait for window
// manager until it tells us it's safe to do so with
// startKeyguardExitAnimatikeyguardGoingAwayon.
Log.i("chensenquan", "======keyguardGoingAway======");
ActivityManager.getService().keyguardGoingAway(flags);
Log.i("chensenquan", "======keyguardGoingAway===flags===");
} catch (RemoteException e) {
Log.e(TAG, "Error while calling WindowManager", e);
}
Trace.endSection();
}
};
19.keyguardGoingAway
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
@Override
public void keyguardGoingAway(int flags) {
enforceNotIsolatedCaller("keyguardGoingAway");
final long token = Binder.clearCallingIdentity();
try {
synchronized (this) {
Log.i("chensenquan", "=======keyguardGoingAway===");
mKeyguardController.keyguardGoingAway(flags);
}
} finally {
Binder.restoreCallingIdentity(token);
}
}
20.keyguardGoingAway
frameworks/base/services/core/java/com/android/server/am/KeyguardController.java
/**
* Called when Keyguard is going away.
*
* @param flags See {@link android.view.WindowManagerPolicy#KEYGUARD_GOING_AWAY_FLAG_TO_SHADE}
* etc.
*/
void keyguardGoingAway(int flags) {
if (!mKeyguardShowing) {
return;
}
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "keyguardGoingAway");
mWindowManager.deferSurfaceLayout();
try {
setKeyguardGoingAway(true);
mWindowManager.prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY,
false /* alwaysKeepCurrent */, convertTransitFlags(flags),
false /* forceOverride */);
updateKeyguardSleepToken();
// Some stack visibility might change (e.g. docked stack)
mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
mStackSupervisor.addStartingWindowsForVisibleActivities(true /* taskSwitch */);
mWindowManager.executeAppTransition();
} finally {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "keyguardGoingAway: surfaceLayout");
mWindowManager.continueSurfaceLayout();
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
}
21.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");
}
synchronized(mWindowMap) {
if (DEBUG_APP_TRANSITIONS) Slog.w(TAG_WM, "Execute app transition: " + mAppTransition
+ " Callers=" + Debug.getCallers(5));
if (mAppTransition.isTransitionSet()) {
mAppTransition.setReady();
final long origId = Binder.clearCallingIdentity();
try {
mWindowPlacerLocked.performSurfacePlacement();
} finally {
Binder.restoreCallingIdentity(origId);
}
}
}
}
22.performSurfacePlacement
frameworks/base/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
final void performSurfacePlacement() {
performSurfacePlacement(false /* force */);
}
final void performSurfacePlacement(boolean force) {
if (mDeferDepth > 0 && !force) {
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;
}
if (mService.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;
}
Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmLayout");
mInLayout = true;
boolean recoveringMemory = false;
if (!mService.mForceRemoves.isEmpty()) {
recoveringMemory = true;
// 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(recoveringMemory);
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);
}
Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
}
23.performSurfacePlacement
frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
// "Something has changed! Let's make it correct now."
// TODO: Super crazy long method that should be broken down...
void performSurfacePlacement(boolean recoveringMemory) {
if (DEBUG_WINDOW_TRACE) Slog.v(TAG, "performSurfacePlacementInner: entry. Called by "
+ Debug.getCallers(3));
int i;
boolean updateInputWindowsNeeded = false;
。。。
final WindowSurfacePlacer surfacePlacer = mService.mWindowPlacerLocked;
// If we are ready to perform an app transition, check through all of the app tokens to be
// shown and see if they are ready to go.
if (mService.mAppTransition.isReady()) {
defaultDisplay.pendingLayoutChanges |=
surfacePlacer.handleAppTransitionReadyLocked();
if (DEBUG_LAYOUT_REPEATS)
surfacePlacer.debugLayoutRepeats("after handleAppTransitionReadyLocked",
defaultDisplay.pendingLayoutChanges);
}
if (!mService.mAnimator.mAppWindowAnimating && mService.mAppTransition.isRunning()) {
// We have finished the animation of an app transition. To do this, we have delayed a
// lot of operations like showing and hiding apps, moving apps in Z-order, etc. The app
// token list reflects the correct Z-order, but the window list may now be out of sync
// with it. So here we will just rebuild the entire app window list. Fun!
defaultDisplay.pendingLayoutChanges |=
mService.handleAnimatingStoppedAndTransitionLocked();
if (DEBUG_LAYOUT_REPEATS)
surfacePlacer.debugLayoutRepeats("after handleAnimStopAndXitionLock",
defaultDisplay.pendingLayoutChanges);
}
...
if (DEBUG_WINDOW_TRACE) Slog.e(TAG,
"performSurfacePlacementInner exit: animating=" + mService.mAnimator.isAnimating());
}
24.handleAppTransitionReadyLocked
frameworks/base/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
/**
* @return bitmap indicating if another pass through layout must be made.
*/
int handleAppTransitionReadyLocked() {
int appsCount = mService.mOpeningApps.size();
if (!transitionGoodToGo(appsCount, mTempTransitionReasons)) {
return 0;
}
Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "AppTransitionReady");
...
mService.mAppTransition.setLastAppTransition(transit, topOpeningApp, topClosingApp);
final AppWindowAnimator openingAppAnimator = (topOpeningApp == null) ? null :
topOpeningApp.mAppAnimator;
final AppWindowAnimator closingAppAnimator = (topClosingApp == null) ? null :
topClosingApp.mAppAnimator;
final int flags = mService.mAppTransition.getTransitFlags();
int layoutRedo = mService.mAppTransition.goodToGo(transit, openingAppAnimator,
closingAppAnimator, mService.mOpeningApps, mService.mClosingApps);
handleNonAppWindowsInTransition(transit, flags);
...
// This has changed the visibility of windows, so perform
// a new layout to get them all up-to-date.
displayContent.setLayoutNeeded();
// TODO(multidisplay): IMEs are only supported on the default display.
final DisplayContent dc = mService.getDefaultDisplayContentLocked();
dc.computeImeTarget(true /* updateImeTarget */);
mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
true /*updateInputWindows*/);
mService.mFocusMayChange = false;
mService.mH.obtainMessage(NOTIFY_APP_TRANSITION_STARTING,
mTempTransitionReasons.clone()).sendToTarget();
Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
return layoutRedo | FINISH_LAYOUT_REDO_LAYOUT | FINISH_LAYOUT_REDO_CONFIG;
}
25.goodToGo
frameworks/base/services/core/java/com/android/server/wm/AppTransition.java
/**
* @return bit-map of WindowManagerPolicy#FINISH_LAYOUT_REDO_* to indicate whether another
* layout pass needs to be done
*/
int goodToGo(int transit, AppWindowAnimator topOpeningAppAnimator,
AppWindowAnimator topClosingAppAnimator, ArraySet<AppWindowToken> openingApps,
ArraySet<AppWindowToken> closingApps) {
mNextAppTransition = TRANSIT_UNSET;
mNextAppTransitionFlags = 0;
setAppTransitionState(APP_STATE_RUNNING);
int redoLayout = notifyAppTransitionStartingLocked(transit,
topOpeningAppAnimator != null ? topOpeningAppAnimator.mAppToken.token : null,
topClosingAppAnimator != null ? topClosingAppAnimator.mAppToken.token : null,
topOpeningAppAnimator != null ? topOpeningAppAnimator.animation : null,
topClosingAppAnimator != null ? topClosingAppAnimator.animation : null);
mService.getDefaultDisplayContentLocked().getDockedDividerController()
.notifyAppTransitionStarting(openingApps, transit);
...
return redoLayout;
}
26.notifyAppTransitionStartingLocked
private int notifyAppTransitionStartingLocked(int transit, IBinder openToken,
IBinder closeToken, Animation openAnimation, Animation closeAnimation) {
int redoLayout = 0;
for (int i = 0; i < mListeners.size(); i++) {
redoLayout |= mListeners.get(i).onAppTransitionStartingLocked(transit, openToken,
closeToken, openAnimation, closeAnimation);
}
return redoLayout;
}
27.init
frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
mWindowManagerInternal.registerAppTransitionListener(new AppTransitionListener() {
@Override
public int onAppTransitionStartingLocked(int transit, IBinder openToken,
IBinder closeToken,
Animation openAnimation, Animation closeAnimation) {
return handleStartTransitionForKeyguardLw(transit, openAnimation);
}
@Override
public void onAppTransitionCancelledLocked(int transit) {
handleStartTransitionForKeyguardLw(transit, null /* transit */);
}
});
28.handleStartTransitionForKeyguardLw
private int handleStartTransitionForKeyguardLw(int transit, @Nullable Animation anim) {
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");
final long startTime = anim != null
? SystemClock.uptimeMillis() + anim.getStartOffset()
: SystemClock.uptimeMillis();
final long duration = anim != null
? anim.getDuration()
: 0;
startKeyguardExitAnimation(startTime, duration);
}
return 0;
}
29.startKeyguardExitAnimation
@Override
public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) {
if (mKeyguardDelegate != null) {
if (DEBUG_KEYGUARD) Slog.d(TAG, "PWM.startKeyguardExitAnimation");
mKeyguardDelegate.startKeyguardExitAnimation(startTime, fadeoutDuration);
}
}
30.startKeyguardExitAnimation
frameworks/base/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) {
if (mKeyguardService != null) {
mKeyguardService.startKeyguardExitAnimation(startTime, fadeoutDuration);
}
}
31.startKeyguardExitAnimation
frameworks/base/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
@Override // Binder interface
public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) {
try {
mService.startKeyguardExitAnimation(startTime, fadeoutDuration);
} catch (RemoteException e) {
Slog.w(TAG , "Remote Exception", e);
}
}
32. startKeyguardExitAnimation
vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
@Override
public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) {
Trace.beginSection("KeyguardService.mBinder#startKeyguardExitAnimation");
checkPermission();
Log.d("chensenquan", "KeyguardService.startKeyguardExitAnimation
startTime=" + startTime + ", fadeoutDuration=" + fadeoutDuration);
mKeyguardViewMediator.startKeyguardExitAnimation(startTime, fadeoutDuration);
Trace.endSection();
}
33.startKeyguardExitAnimation
vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) {
Trace.beginSection("KeyguardViewMediator#startKeyguardExitAnimation");
Log.i("chensenquan1", "=======startKeyguardExitAnimation======");
Message msg = mHandler.obtainMessage(START_KEYGUARD_EXIT_ANIM,
new StartKeyguardExitAnimParams(startTime, fadeoutDuration));
mHandler.sendMessage(msg);
Log.i("chensenquan1", "=======startKeyguardExitAnimation11======");
Trace.endSection();
}
34. START_KEYGUARD_EXIT_ANIM → handleStartKeyguardExitAnimation
private void handleStartKeyguardExitAnimation(long startTime, long fadeoutDuration) {
Trace.beginSection("KeyguardViewMediator#handleStartKeyguardExitAnimation");
if (DEBUG) Log.d(TAG, "handleStartKeyguardExitAnimation startTime=" + startTime
+ " fadeoutDuration=" + fadeoutDuration);
Log.i("chensenquan1", "======handleStartKeyguardExitAnimation======");
synchronized (KeyguardViewMediator.this) {
Log.d("chensenquan", "KeyguardViewMediator.handleStartKeyguardExitAnimation
mHiding=" + mHiding + ", mWakeAndUnlocking=" + mWakeAndUnlocking
+ ", mShowing=" + mShowing);
if (!mHiding) {
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.
mStatusBarKeyguardViewManager.getViewRootImpl().setReportNextDraw();
notifyDrawn(mDrawnCallback);
mDrawnCallback = null;
}
Log.d("chensenquan", "KeyguardViewMediator.handleStartKeyguardExitAnimation 11111");
// only play "unlock" noises if not on a call (since the incall UI
// disables the keyguard)
///M: fix ALPS01933919 to avoid play unlock sound continuously.
/// also fixes ALPS01940830
if (TelephonyManager.EXTRA_STATE_IDLE.equals(mPhoneState) && mShowing) {
playSounds(false);
}
mWakeAndUnlocking = false;
setShowingLocked(false);
mDismissCallbackRegistry.notifyDismissSucceeded();
Log.d("chensenquan", "KeyguardViewMediator.handleStartKeyguardExitAnimation 222");
mStatusBarKeyguardViewManager.hide(startTime, fadeoutDuration);
Log.d("chensenquan", "KeyguardViewMediator.handleStartKeyguardExitAnimation 333");
resetKeyguardDonePendingLocked();
mHideAnimationRun = false;
adjustStatusBarLocked();
sendUserPresentBroadcast();
mUpdateMonitor.setKeyguardGoingAway(false /* goingAway */);
// Added by lei.ye.hz for Task 5362432 on 2017/11/17 begin
mUpdateMonitor.setKeyguardDoneOnGoing(false);
// Added by lei.ye.hz for Task 5362432 on 2017/11/17 end
}
Log.d(TAG, "set mKeyguardDoneOnGoing = false");
mKeyguardDoneOnGoing = false;
Trace.endSection();
}
以下所有分析数据Log基于eng版本,user版本会更快;
添加Log分析1s耗时来自于哪里,具体结果如下,可看出主要有3个耗时:
1、获取解锁结果,耗时大约200ms;----------无法优化
2、KeyguardPINView执行disappear动画startDisappearAnimation,耗时大约300ms;---------可以去掉,去掉不影响显示
3、等待窗口却换完毕再完全隐藏keyguard,耗时大约400ms;-----------需要系统做整体优化,如comment#1,zhangku会整体优化
----------按下确认键,开始解锁
08-22 01:23:18.985 16166 16166 D UiReactionTimeTest: Perform unlockscreen action from Swipe mode at 1534915398985 ms
****中间有200ms等待-----获取解锁结果,这个耗时无法优化
----------解锁完毕,获取解锁结果
08-22 01:23:19.180 16166 16166 D yjrkeyguard: KeyguardAbsKeyInputView.onPasswordChecked matched=true, isValidPassword=true
08-22 01:23:19.184 16166 16166 D KeyguardSecurityView: showNextSecurityScreenOrFinish(true)
08-22 01:23:19.184 16166 16166 D KeyguardSecurityView: showNext.. mCurrentSecuritySelection = PIN
08-22 01:23:19.184 16166 16166 D KeyguardSecurityView: showNextSecurityScreenOrFinish() - authenticated is True, and mCurrentSecuritySelection = PIN
08-22 01:23:19.195 16166 16166 V KeyguardSecurityView: securityMode = PIN
08-22 01:23:19.195 16166 16166 D KeyguardSecurityView: mCurrentSecuritySelection: PIN
08-22 01:23:19.195 16166 16166 D KeyguardViewMediator: updateNavbarStatus() is called.
08-22 01:23:19.197 16166 16166 D yjrkeyguard: KeyguardHostView.finish mViewMediatorCallback not null deferKeyguardDone=false
08-22 01:23:19.204 16166 16166 D yjrkeyguard: KeyguardViewMediator.tryKeyguardDone startPreHideAnimation(mHideAnimationFinishedRunnable)
08-22 01:23:19.205 16166 16166 D yjrkeyguard: StatusBarKeyguardViewManager.startPreHideAnimation mBouncer.isShowing=true
08-22 01:23:19.205 16166 16166 D yjrkeyguard: KeyguardBouncer.startPreHideAnimation mKeyguardView=com.android.keyguard.KeyguardHostView{582332 V.E...... ........ 0,84-480,759 #7f0a0148 app:id/keyguard_host_view} runnable=com.android.systemui.keyguard.-$Lambda$sJEWzSUgVYHCfk83FvvFNEzkKS4@3b06ec6
08-22 01:23:19.206 16166 16166 D yjrkeyguard: KeyguardSecurityContainer.startDisappearAnimation mCurrentSecuritySelection=PIN
-----开始执行一个disappear动画 disappearAnimationUtils.startAnimation2d
08-22 01:23:19.208 16166 16166 D yjrkeyguard: KeyguardPINView.startDisappearAnimation needsSlowUnlockTransition=false
08-22 01:23:19.215 16166 16166 D KeyguardSecurityView: finish
08-22 01:23:19.215 16166 16166 D KeyguardSecurityView: showNextSecurityScreenOrFinish() - return finish = true
****中间有320ms动画延时操作,实际是125*1.5=187.5ms,这个时间可以去掉,没有实际效果
-----disappear动画执行完毕
08-22 01:23:19.524 16166 16166 D yjrkeyguard: KeyguardPINView.startDisappearAnimation.run start finishRunnable.run
08-22 01:23:19.524 16166 16166 D yjrkeyguard: KeyguardViewMediator.tryKeyguardDone
08-22 01:23:19.525 16166 16166 D KeyguardViewMediator: handleKeyguardDone
08-22 01:23:19.526 16166 16166 D KeyguardViewMediator: handleKeyguardDone before check remote lock
08-22 01:23:19.528 16166 16166 D yjrkeyguard: KeyguardViewMediator.handleKeyguardDone
08-22 01:23:19.528 16166 16166 D KeyguardViewMediator: handleHide
08-22 01:23:19.529 16166 16166 D yjrkeyguard: KeyguardViewMediator.handleHide mShowing=true, mOccluded=false
08-22 01:23:19.529 16166 16166 D KeyguardViewMediator: keyguardGoingAway
----------开始等待WindowManager却换窗口成功
08-22 01:23:19.529 16166 16166 D yjrkeyguard: KeyguardViewMediator.mKeyguardGoingAwayRunnable start setKeyguardGoingAway
08-22 01:23:19.530 2950 3965 D yjrkeyguard: AMS keyguardGoingAway
****中间有400ms等待,窗口却换动作,需要系统组看看是否有优化空间
-----等待完毕开始执行移除Keyguard动作
08-22 01:23:19.939 16166 16197 D yjrkeyguard: KeyguardService.startKeyguardExitAnimation startTime=14267802, fadeoutDuration=150
08-22 01:23:19.940 16166 16166 D yjrkeyguard: KeyguardViewMediator.mHandler START_KEYGUARD_EXIT_ANIM
08-22 01:23:19.940 16166 16166 D KeyguardViewMediator: handleStartKeyguardExitAnimation startTime=14267802 fadeoutDuration=150
08-22 01:23:19.941 16166 16166 D yjrkeyguard: KeyguardViewMediator.handleStartKeyguardExitAnimation mHiding=true, mWakeAndUnlocking=false, mShowing=true
08-22 01:23:19.941 16166 16166 D yjrkeyguard: KeyguardViewMediator.handleStartKeyguardExitAnimation 11111
08-22 01:23:19.941 16166 16166 D KeyguardViewMediator: playSounds(locked = false), mSuppressNextLockSound =false
08-22 01:23:19.945 16166 16166 D yjrkeyguard: KeyguardViewMediator.handleStartKeyguardExitAnimation 222
08-22 01:23:20.034 16166 16166 D StatusBarKeyguardViewManager: updateStates() - setBouncerShowing(false)
08-22 01:23:20.060 16166 16166 D yjrkeyguard: KeyguardViewMediator.handleStartKeyguardExitAnimation 333
08-22 01:23:20.064 16166 16166 D KeyguardViewMediator: adjustStatusBarLocked: mShowing=false mOccluded=false isSecure=true --> flags=0x0
08-22 01:23:20.068 16166 16166 D KeyguardViewMediator: set mKeyguardDoneOnGoing = false