解锁流程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

android PIN码解锁流程相关推荐

  1. Android sim卡 pin码解锁流程.

    sim卡 pin码解锁流程 1. PIN码解锁界面属于Phone Policy的一部分,代码位置在 \frameworks\base\policy\src\com\android\internal\p ...

  2. Android11 PIN码解锁分析

    在上一篇文章里我们分析了手势绘制解锁的整个流程,这次我们来分析一下PIN码解锁时所相关的内容 布局 在我们分析流程之前,我们先来看到KeyguardPINView这个类,他是用于显示解锁的 PIN 键 ...

  3. android 解锁流程,Android Q 指纹解锁流程

    Android Q 指纹解锁流程 // Authentation Finger Schedule: (close Screen, Authentation with finger(Success)) ...

  4. 你的PIN不可用,单击以重新设置PIN,无法通过pin码解锁电脑(超快超简单的解决办法)

    一.问题 如果你和我一样,把系统配置里面的启动选项改成了诊断启动或者有选择的启动 然后电脑重启了,就出现"你的pin不可用,单击以重新设置", 有的人的电脑有账户密码,但是那玩意儿 ...

  5. android pin快速解锁,[android]解锁更有趣更安全–TimePIN(时间解锁)

    TimePIN(时间解锁):手机隐私在日常生活非常重要,因为不想被别人知道,我们通常会设置锁屏密码来保护隐私.不过熟悉你的人可能会猜到密码,但是经常更换密码既麻烦又容易忘,TimePIN这一款软件比较 ...

  6. Android源码编译流程及所需的编译环境

    编译过程: 下载源码->搭建编译环境->编译源码->解决编译报错->生成编译固件包 编译环境 本文使用的是下载好的Android8.1源码,搭建好的虚拟机Ubuntu14.0/ ...

  7. android pin码 经典蓝牙_Android蓝牙开发—经典蓝牙详细开发流程

    Android蓝牙开发-经典蓝牙详细开发流程 发布时间:2018-07-16 13:41, 浏览次数:637 , 标签: Android Android蓝牙开发前,首先要区分是经典蓝牙开发还是BLE( ...

  8. android pin快速解锁,【Android开发】PIN解锁|EditText入门

    心得感悟 这个Demo的确不难,但让自己写还是不能写出来.因为之前没有学过Android开发的一些方法控件,每次布置的Demo都写不出来,还是挺挫败的.而且因为开学事情有点多,预习任务也没能好好完成, ...

  9. Android 源码 installPackage 流程分析

    installPackage 安装流程最终会调用 PackageManagerService 对应方法,当然是使用 binder 机制得以实现跨进程通信. 先来看看 installPackage 流程 ...

  10. android pin码 经典蓝牙_Android 蓝牙 pin 自动配 setPin()方法有时候无效

    2018-08-09 Android  蓝牙pin自动配对ClsUtils类中的 static public boolean setPin(Class btClass, BluetoothDevice ...

最新文章

  1. 查看Firefox中的缓存
  2. 创建docker容器时出现 docker: Error response from daemon, The container name is already in use by container
  3. 双指针解决数组排序问题
  4. TensorRT(4)-Profiling and 16-bit Inference
  5. oracle某个存过的执行时间,java – 为什么oracle存储过程的执行时间会大大增加,具体取决于它的执行方式?...
  6. Docker镜像与容器命令 专题
  7. js / php 网站底部版权文字自动改变年份
  8. 网站云服务器资料本地备份,云服务器上备份本地数据
  9. Victor and World(spfa+状态压缩dp)
  10. ExtAspNet公司项目截图
  11. neo4j︱neo4j批量导入neo4j-import (五)
  12. 面试官上来就问:能不能开发一个微信朋友圈、推特?我有点懵~
  13. 【深度学习】之Caffe的solver文件配置(转载自csdn)
  14. 如何免费创建三级域名?
  15. 新词发现-helloNLP
  16. [Lua基础]操作系统库——Date,Time,Clock
  17. 联发科技嵌入式_从机械到嵌入式开发,一个研究僧的联发科实习经验分享
  18. 用JS实现猜数字游戏
  19. 使用cmd命令远程重启服务器
  20. How Gradual Typing System Helps Us

热门文章

  1. no version information available问题解决
  2. Word控件Spire.Doc 转换教程(二十一):将非标准字体的word文档转换为PDF
  3. 5G手机的赛点争夺战
  4. NSUOJ2888最小唯一表示前缀(偷懒的xzj)
  5. HDU - 1728 逃离迷宫 【BFS】
  6. 计算机快速看图教程,CAD快速看图教程:CAD图纸测量方法集锦
  7. 华为篇-嵌入式公司待遇盘点-第二期
  8. word方式编辑EPUB电子书
  9. 建立统分结合、职责明确的疾控可持续发展信息化体系
  10. 我的团长我的团第十四集