上锁的主要是两个步骤
- 设备加密,这块主要是与android管理设备密码服务相关
- 显示锁屏界面,即展开通知面板,同时加载密码界面的布局,但是会隐藏起来,等到向上划去锁屏界面才显示
- 更新activity stack的状态,锁屏下的activity会被置为onstop
执行上锁的流程是调用KeyguardViewMediator的doKeyguardLocked函数来完成的
private void doKeyguardLocked(Bundle options) {
if (!mExternallyEnabled) {
return;
}
// if the keyguard is already showing, don't bother
if (mStatusBarKeyguardViewManager.isShowing()) {
resetStateLocked();
return;
}
if (!mustNotUnlockCurrentUser() || !mUpdateMonitor.isDeviceProvisioned()) {
final boolean requireSim = !SystemProperties.getBoolean("keyguard.no_require_sim", false);
final boolean absent = SubscriptionManager.isValidSubscriptionId(
mUpdateMonitor.getNextSubIdForState(IccCardConstants.State.ABSENT));
final boolean disabled = SubscriptionManager.isValidSubscriptionId(
mUpdateMonitor.getNextSubIdForState(IccCardConstants.State.PERM_DISABLED));
final boolean lockedOrMissing = mUpdateMonitor.isSimPinSecure()
|| ((absent || disabled) && requireSim);
if (!lockedOrMissing && shouldWaitForProvisioning()) {
return;
}
if (mLockPatternUtils.isLockScreenDisabled(KeyguardUpdateMonitor.getCurrentUser())
&& !lockedOrMissing) {
return;
}
if (mLockPatternUtils.checkVoldPassword(KeyguardUpdateMonitor.getCurrentUser())) {
setShowingLocked(false);
hideLocked();
mUpdateMonitor.reportSuccessfulStrongAuthUnlockAttempt();
return;
}
}
showLocked(options);
}
重点看这个showLocked函数,经过handler的传递会调到handleShow
private void handleShow(Bundle options) {
final int currentUser = KeyguardUpdateMonitor.getCurrentUser();
if (mLockPatternUtils.isSecure(currentUser)) {
mLockPatternUtils.getDevicePolicyManager().reportKeyguardSecured(currentUser); //更新设备加密状态
}
synchronized (KeyguardViewMediator.this) {
if (!mSystemReady) {
return;
} else {
}
setShowingLocked(true);
mStatusBarKeyguardViewManager.show(options); // 显示锁屏界面和加载bouncer
mHiding = false;
mWakeAndUnlocking = false;
resetKeyguardDonePendingLocked();
mHideAnimationRun = false;
updateActivityLockScreenState(); // 更新activitystack的状态
adjustStatusBarLocked();
userActivity();
mShowKeyguardWakeLock.release();
}
mKeyguardDisplayManager.show();
}
继续看显示锁屏的函数
public void show(Bundle options) {
mShowing = true;
mStatusBarWindowManager.setKeyguardShowing(true); // 调整状态栏的窗口状态
mScrimController.abortKeyguardFadingOut();
reset();
}
public void reset() {
if (mShowing) {
if (mOccluded) {// 特殊情况,例如来电,音乐锁屏等显示在锁屏界面上的activity
mPhoneStatusBar.hideKeyguard();
mPhoneStatusBar.stopWaitingForKeyguardExit();
mBouncer.hide(false /* destroyView */);
} else {
showBouncerOrKeyguard();
}
KeyguardUpdateMonitor.getInstance(mContext).sendKeyguardReset();
updateStates();
}
}
正常情况下都会调用到showBouncerOrKeyguard()
protected void showBouncerOrKeyguard() {
if (mBouncer.needsFullscreenBouncer()) { // 存在锁定的sim卡会走到这里
// The keyguard might be showing (already). So we need to hide it.
mPhoneStatusBar.hideKeyguard();
mBouncer.show(true /* resetSecuritySelection */);
} else {
mPhoneStatusBar.showKeyguard(); // 展开下拉面板
mBouncer.hide(false /* destroyView */); // 隐藏bouncer
mBouncer.prepare(); // 加载bouncer的布局
}
}
所以正常情况下就会调用上面三段函数,主要关注bouncer布局的加载
经过一系列调用,会到达KeyguardSecurityContainer的showPrimarySecurityScreen
void showPrimarySecurityScreen(boolean turningOff) {
SecurityMode securityMode = mSecurityModel.getSecurityMode(); // 获取锁屏密码样式
if (DEBUG) Log.v(TAG, "showPrimarySecurityScreen(turningOff=" + turningOff + ")");
showSecurityScreen(securityMode); // 加载具体的布局
}
private void showSecurityScreen(SecurityMode securityMode) {
if (securityMode == mCurrentSecuritySelection) return;
KeyguardSecurityView oldView = getSecurityView(mCurrentSecuritySelection);
KeyguardSecurityView newView = getSecurityView(securityMode);
// Emulate Activity life cycle
if (oldView != null) {
oldView.onPause();
oldView.setKeyguardCallback(mNullCallback); // ignore requests from old view
}
if (securityMode != SecurityMode.None) {
newView.onResume(KeyguardSecurityView.VIEW_REVEALED);
newView.setKeyguardCallback(mCallback);
}
// Find and show this child.
final int childCount = mSecurityViewFlipper.getChildCount();
final int securityViewIdForMode = getSecurityViewIdForMode(securityMode);
for (int i = 0; i < childCount; i++) {
if (mSecurityViewFlipper.getChildAt(i).getId() == securityViewIdForMode) {
mSecurityViewFlipper.setDisplayedChild(i);
break;
}
}
mCurrentSecuritySelection = securityMode;
mSecurityCallback.onSecurityModeChanged(securityMode,
securityMode != SecurityMode.None && newView.needsInput());
}
最后,通过锁定方式来找到对应的布局,就完成的bouncer的加载,划去锁屏界面后就可以看到了
private int getSecurityViewIdForMode(SecurityMode securityMode) {
switch (securityMode) {
case Pattern: return R.id.keyguard_pattern_view;
case PIN: return R.id.keyguard_pin_view;
case Password: return R.id.keyguard_password_view;
case SimPin: return R.id.keyguard_sim_pin_view;
case SimPuk: return R.id.keyguard_sim_puk_view;
}
return 0;
}
放一张时序图