一、锁屏核心组成
Android锁屏流程分析,核心的类有KeyguardViewMediator、keyguardUpdateMonitor、keyguardBouncer等。
KeyguardViewMediator继承SystemUI,是锁屏的核心类,是交互的中转类,其它对象都通过KeyguardViewMediator对象相互交互。
keyguardUpdateMonitor是状态回调的管理类。
keyguardBouncer是锁屏view的通信交互类。
二、锁屏开机分析
锁屏keyguard属于SystemUI,锁屏开机大致分为两部分,第一部分是KeyguardViewMediator的启动;第二部分是从WindowManagerService开始,处理锁屏显示等流程。
KeyguardViewMediator继承SystemUI,所以KeyguardViewMediator的启动和SystemUI的启动一致。这里着重分析第二部分。
2.1 SystemServer
SystemServer在启动SystemUI的方法上,最后调用WindowManagerService的onSystemUiStarted方法。
static final void startSystemUi(Context context, WindowManagerService windowManager) {
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.android.systemui",
"com.android.systemui.SystemUIService"));
intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
//Slog.d(TAG, "Starting service: " + intent);
context.startServiceAsUser(intent, UserHandle.SYSTEM);
windowManager.onSystemUiStarted();
}
2.2 WindowManagerService
WindowManagerService继承于IWindowManager.Stub, 作为Binder服务端。实际处理window的是PhoneWindowManager类,在SystemServer创建WindowManagerService时传入。
wm = WindowManagerService.main(context, inputManager,
mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
!mFirstBoot, mOnlyCore, new PhoneWindowManager());
ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
/* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
traceEnd();
WindowManagerService的onSystemUiStarted方法,实际调用的是PhoneWindowManager。
2.3 PhoneWindowManager
在PhoneWindowManager中会调用bindKeyguard,KeyguardServiceDelegate作为KeyguardService的委派。
private void bindKeyguard() {
synchronized (mLock) {
if (mKeyguardBound) {
return;
}
mKeyguardBound = true;
}
mKeyguardDelegate.bindService(mContext);
}
2.4 KeyguardService
Delegate
KeyguardServiceDelegate在bindService方法中绑定KeyguardService。
public void bindService(Context context) {
Intent intent = new Intent();
final Resources resources = context.getApplicationContext().getResources();
//从配置文件中获取KeyguardService
final ComponentName keyguardComponent = ComponentName.unflattenFromString(
resources.getString(com.android.internal.R.string.config_keyguardComponent));
intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
intent.setComponent(keyguardComponent);
//绑定KeyguardService
if (!context.bindServiceAsUser(intent, mKeyguardConnection,
Context.BIND_AUTO_CREATE, mHandler, UserHandle.SYSTEM)) {
Log.v(TAG, "*** Keyguard: can't bind to " + keyguardComponent);
mKeyguardState.showing = false;
mKeyguardState.showingAndNotOccluded = false;
mKeyguardState.secure = false;
synchronized (mKeyguardState) {
// TODO: Fix synchronisation model in this class. The other state in this class
// is at least self-healing but a race condition here can lead to the scrim being
// stuck on keyguard-less devices.
mKeyguardState.deviceHasKeyguard = false;
}
} else {
if (DEBUG) Log.v(TAG, "*** Keyguard started");
}
}
在ServiceConnection的连接成功回调中,创建KeyguardService包装类KeyguardServiceWrapper。包装类除了KeyguardService,还有KeyguardStateMonitor状态监视器。实际调用还是通过KeyguardService。
private final ServiceConnection mKeyguardConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//将KeyguardServicer传入包装类
mKeyguardService = new KeyguardServiceWrapper(mContext,
IKeyguardService.Stub.asInterface(service), mCallback);
if (mKeyguardState.systemIsReady) {
// If the system is ready, it means keyguard crashed and restarted.
mKeyguardService.onSystemReady();
if (mKeyguardState.currentUser != UserHandle.USER_NULL) {
// There has been a user switch earlier
mKeyguardService.setCurrentUser(mKeyguardState.currentUser);
}
// This is used to hide the scrim once keyguard displays.
if (mKeyguardState.interactiveState == INTERACTIVE_STATE_AWAKE
|| mKeyguardState.interactiveState == INTERACTIVE_STATE_WAKING) {
mKeyguardService.onStartedWakingUp();
}
if (mKeyguardState.interactiveState == INTERACTIVE_STATE_AWAKE) {
mKeyguardService.onFinishedWakingUp();
}
if (mKeyguardState.screenState == SCREEN_STATE_ON
|| mKeyguardState.screenState == SCREEN_STATE_TURNING_ON) {
mKeyguardService.onScreenTurningOn(
new KeyguardShowDelegate(mDrawnListenerWhenConnect));
}
if (mKeyguardState.screenState == SCREEN_STATE_ON) {
mKeyguardService.onScreenTurnedOn();
}
}
...
}
...
2.5 KeyguardService
KeyguardService内部由KeyguardViewMediator和KeyguardLifecyclesDispatcher组成,KeyguardViewMediator和windowmanager的通信实际是KeyguardService的IPC通信。
static final String TAG = "KeyguardService";
static final String PERMISSION = android.Manifest.permission.CONTROL_KEYGUARD;
private KeyguardViewMediator mKeyguardViewMediator;
private KeyguardLifecyclesDispatcher mKeyguardLifecyclesDispatcher;
@Override
public void onCreate() {
((SystemUIApplication) getApplication()).startServicesIfNeeded();
mKeyguardViewMediator =
((SystemUIApplication) getApplication()).getComponent(KeyguardViewMediator.class);
mKeyguardLifecyclesDispatcher = new KeyguardLifecyclesDispatcher(
Dependency.get(ScreenLifecycle.class),
Dependency.get(WakefulnessLifecycle.class));
}
在KeyguardService绑定成功后调用了onSystemReady方法。onSystemReady最终的处理流程是在KeyguardViewMediator的onSystemReady方法。
2.6 KeyguardViewMediator
onSystemReady方法发送了一条handler消息。经过消息传递会由handleSystemReady方法处理。handleSystemReady方法的关键调用是doKeyguardLocked。
public void onSystemReady() {
mHandler.obtainMessage(SYSTEM_READY).sendToTarget();
}
----------------
private void handleSystemReady() {
synchronized (this) {
if (DEBUG) Log.d(TAG, "onSystemReady");
mSystemReady = true;
//关键处理
doKeyguardLocked(null);
mUpdateMonitor.registerCallback(mUpdateCallback);
}
// Most services aren't available until the system reaches the ready state, so we
// send it here when the device first boots.
maybeSendUserPresentBroadcast();
}
doKeyguardLocked是启动锁屏界面的预处理方法。主要处理有
判断其他应用禁止锁屏呈现。
判断是否需要重置状态。
判断Settings中没有启用锁屏 。
判断是否设置了密码等。
符合条件,显示锁屏。
private void doKeyguardLocked(Bundle options) {
...
//1. 判断其他应用禁止锁屏呈现。
//2. 判断是否需要重置状态。
//3. 判断Settings中没有启用锁屏 。
//4. 判断是否设置了密码等。
...
//显示锁屏
if (DEBUG) Log.d(TAG, "doKeyguard: showing the lock screen");
showLocked(options);
}
showLocked显示锁屏方法主要处理:请求CPU不休眠,发送显示锁屏消息。
private void showLocked(Bundle options) {
Trace.beginSection("KeyguardViewMediator#showLocked aqcuiring mShowKeyguardWakeLock");
if (DEBUG) Log.d(TAG, "showLocked");
// ensure we stay awake until we are finished displaying the keyguard
// 获取PARTIAL_WAKE_LOCK,不受电源键影响,不让CPU进入休眠状态
mShowKeyguardWakeLock.acquire();
Message msg = mHandler.obtainMessage(SHOW, options);
mHandler.sendMessage(msg);
Trace.endSection();
}
处理锁屏消息的方法在handleShow,在handleShow中调用StatusBarKeyguardViewManager方法,锁屏处理由KeyguardViewMediator转移到StatusBarKeyguardViewManager。
private void handleShow(Bundle options) {
Trace.beginSection("KeyguardViewMediator#handleShow");
final int currentUser = KeyguardUpdateMonitor.getCurrentUser();
if (mLockPatternUtils.isSecure(currentUser)) {
mLockPatternUtils.getDevicePolicyManager().reportKeyguardSecured(currentUser);
}
synchronized (KeyguardViewMediator.this) {
if (!mSystemReady) {
if (DEBUG) Log.d(TAG, "ignoring handleShow because system is not ready.");
return;
} else {
if (DEBUG) Log.d(TAG, "handleShow");
}
setShowingLocked(true, mAodShowing);
//展示锁屏界面
mStatusBarKeyguardViewManager.show(options);
mHiding = false;
mWakeAndUnlocking = false;
resetKeyguardDonePendingLocked();
mHideAnimationRun = false;
adjustStatusBarLocked();
userActivity();
mShowKeyguardWakeLock.release();
}
mKeyguardDisplayManager.show();
}
2.7 StatusBarKeyguardViewManager
show方法设置keyguard是否显示,通知statusbar显示锁屏,重置view的状态,进行锁屏。
public void show(Bundle options) {
mShowing = true;
mStatusBarWindowManager.setKeyguardShowing(true);
//重置状态
reset(true /* hideBouncerWhenShowing */);
StatsLog.write(StatsLog.KEYGUARD_STATE_CHANGED,
StatsLog.KEYGUARD_STATE_CHANGED__STATE__SHOWN);
}
reset方法,主要调用showBouncerOrKeyguard方法。
public void reset(boolean hideBouncerWhenShowing) {
if (mShowing) {
if (mOccluded && !mDozing) {
mStatusBar.hideKeyguard();
if (hideBouncerWhenShowing || mBouncer.needsFullscreenBouncer()) {
hideBouncer(false /* destroyView */);
}
} else {
showBouncerOrKeyguard(hideBouncerWhenShowing);
}
KeyguardUpdateMonitor.getInstance(mContext).sendKeyguardReset();
updateStates();
}
}
showBouncerOrKeyguard方法,判断显示默认锁屏界面还是显示密码锁屏。默认锁屏界面由StatusBar管理,而密码解锁则调用KeyguardBouncer类。
protected void showBouncerOrKeyguard(boolean hideBouncerWhenShowing) {
//是否需要显示密码锁屏界面
if (mBouncer.needsFullscreenBouncer() && !mDozing) {
// The keyguard might be showing (already). So we need to hide it.
//隐藏锁屏,显示密码解锁界面
mStatusBar.hideKeyguard();
mBouncer.show(true /* resetSecuritySelection */);
} else {
mStatusBar.showKeyguard();
if (hideBouncerWhenShowing) {
hideBouncer(shouldDestroyViewOnReset() /* destroyView */);
mBouncer.prepare();
}
}
updateStates();
}
2.8 KeyguardBouncer
在StatusBarKeyguardViewManager类中,StatusBar类则管理默认锁屏界面,KeyguardBouncer类控制密码解锁界面的,KeyguardBouncer会进行锁屏view的填充,KeyguardHostView是自定义容器,内部锁屏相关的处理在KeyguardSecurityContainer中。
public void showPrimarySecurityScreen() {
if (DEBUG) Log.d(TAG, "show()");
mSecurityContainer.showPrimarySecurityScreen(false);
}
2.9 KeyguardSecurityContainer
在showSecurityScreen方法中会根据锁屏的类型获得锁屏的view,并添加到KeyguardSecurityViewFlipper 。
private void showSecurityScreen(SecurityMode securityMode) {
if (DEBUG) Log.d(TAG, "showSecurityScreen(" + securityMode + ")");
if (securityMode == mCurrentSecuritySelection) return;
KeyguardSecurityView oldView = getSecurityView(mCurrentSecuritySelection);
KeyguardSecurityView newView = getSecurityView(securityMode);
// Emulate Activity life cycle
if (oldView != null) {
oldView.onPause();
oldView.setKeyguardCallback(mNullCallback); // ignore requests from old view
}
if (securityMode != SecurityMode.None) {
newView.onResume(KeyguardSecurityView.VIEW_REVEALED);
newView.setKeyguardCallback(mCallback);
}
// Find and show this child.
final int childCount = mSecurityViewFlipper.getChildCount();
final int securityViewIdForMode = getSecurityViewIdForMode(securityMode);
for (int i = 0; i < childCount; i++) {
if (mSecurityViewFlipper.getChildAt(i).getId() == securityViewIdForMode) {
mSecurityViewFlipper.setDisplayedChild(i);
break;
}
}
mCurrentSecuritySelection = securityMode;
mSecurityCallback.onSecurityModeChanged(securityMode,
securityMode != SecurityMode.None && newView.needsInput());
}
private KeyguardSecurityView getSecurityView(SecurityMode securityMode) {
final int securityViewIdForMode = getSecurityViewIdForMode(securityMode);
KeyguardSecurityView view = null;
final int children = mSecurityViewFlipper.getChildCount();
for (int child = 0; child < children; child++) {
if (mSecurityViewFlipper.getChildAt(child).getId() == securityViewIdForMode) {
view = ((KeyguardSecurityView)mSecurityViewFlipper.getChildAt(child));
break;
}
}
int layoutId = getLayoutIdFor(securityMode);
if (view == null && layoutId != 0) {
final LayoutInflater inflater = LayoutInflater.from(mContext);
if (DEBUG) Log.v(TAG, "inflating id = " + layoutId);
View v = inflater.inflate(layoutId, mSecurityViewFlipper, false);
mSecurityViewFlipper.addView(v);
updateSecurityView(v);
view = (KeyguardSecurityView)v;
}
return view;
}
2.10 StatusBar
StatusBar也是继承SystemUI,启动流程和SystemUI一致。并在star的时候添加创建StatusBar相关的view。
protected void makeStatusBarView() {
...
// 创建 NotificationPanelView
mNotificationPanel = mStatusBarWindow.findViewById(R.id.notification_panel);
mStackScroller = mStatusBarWindow.findViewById(R.id.notification_stack_scroller);
mZenController.addCallback(this);
...
//创建 KeyguardStatusBarView
mKeyguardStatusBar = mStatusBarWindow.findViewById(R.id.keyguard_header);
StatusBar管理锁屏状态的layout主要在NotificationPanelView,把KeyguardBottomAreaView添加到NotificationPanelView中。
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mKeyguardStatusBar = findViewById(R.id.keyguard_header);
mKeyguardStatusView = findViewById(R.id.keyguard_status_view);
mNotificationContainerParent = findViewById(R.id.notification_container_parent);
mNotificationStackScroller = findViewById(R.id.notification_stack_scroller);
//填充锁屏图标的layout
mKeyguardBottomArea = findViewById(R.id.keyguard_bottom_area);
mQsNavbarScrim = findViewById(R.id.qs_navbar_scrim);
mLastOrientation = getResources().getConfiguration().orientation;
initBottomArea();
mQsFrame = findViewById(R.id.qs_frame);
}
KeyguardBottomAreaView是默认锁屏界面的底部view,包括锁图标、打开摄像头等自定义功能。
/**
* Implementation for the bottom area of the Keyguard, including camera/phone affordance and status
* text.
*/
public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickListener,
UnlockMethodCache.OnUnlockMethodChangedListener,
AccessibilityController.AccessibilityStateChangedCallback, View.OnLongClickListener {
...
}
三、息屏分析
息屏的处理是从PowerManager开始,最终到锁屏的核心类KeyguardViewMediator,息屏处理的大致流程如下:
3.1 powerManager
powerManager是电源状态和power键处理的管理类。锁屏的息屏和亮屏都从powerManager类开始处理。按power键息屏会调用powerManager的goToSleep方法,而powerManager的处理是PowerManagerService类,所以是远程调用了PowerManagerService的goToSleep。
public void goToSleep(long time, int reason, int flags) {
try {
mService.goToSleep(time, reason, flags);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
3.2 PowerManagerService
PowerManagerService对于goToSleep的处理流程如下。
goToSleep –> goToSleepInternal –> updatePowerStateLocked –> goToSleepNoUpdateLocked –>setWakefulnessLocked
经过一系列的调用,最终会走到setWakefulnessLocked方法,在方法内部调用了Notifier的
onWakefulnessChangeStarted方法。Notifier是PMS模块中用于进行“通知”的一个组件类。
@Override // Binder call
public void goToSleep(long eventTime, int reason, int flags) {
...
try {
goToSleepInternal(eventTime, reason, flags, uid);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
@VisibleForTesting
void setWakefulnessLocked(int wakefulness, int reason) {
if (mWakefulness != wakefulness) {
mWakefulness = wakefulness;
mWakefulnessChanging = true;
mDirty |= DIRTY_WAKEFULNESS;
if (mNotifier != null) {
mNotifier.onWakefulnessChangeStarted(wakefulness, reason);
}
}
}
3.3 Notifier
在onWakefulnessChangeStarted方法中,分别对ActivityManager、InputManager进行通知以及调用handleEarlyInteractiveChange方法。
public void onWakefulnessChangeStarted(final int wakefulness, int reason) {
mHandler.post(new Runnable() {
@Override
public void run() {
//ActivityManager处理 mActivityManagerInternal.onWakefulnessChanged(wakefulness);
}
});
if (mInteractive != interactive) {
//InputManager处理
mInputManagerInternal.setInteractive(interactive);
mInputMethodManagerInternal.setInteractive(interactive);
// Notify battery stats.
try {
mBatteryStats.noteInteractive(interactive);
} catch (RemoteException ex) { }
handleEarlyInteractiveChange();
}
}
handleEarlyInteractiveChange方法的核心是调用了WindowManagerPolicy方法,WindowManagerPolicy的实现类是PhoneWindowManager,所以处理转移到了PhoneWindowManager上。
private void handleEarlyInteractiveChange() {
synchronized (mLock) {
if (mInteractive) {
// Waking up…
mHandler.post(new Runnable() {
@Override
public void run() {
mPolicy.startedWakingUp();
}
});
} else {
mHandler.post(new Runnable() {
@Override
public void run() {
mPolicy.startedGoingToSleep(why);
}
});
}
}
}
3.4 PhoneWindowManager
startedGoingToSleep方法内调用了KeyguardServiceDelegate类,在锁屏开机流程的分析中已经知道KeyguardServiceDelegate最终会调用KeyguardViewMediator锁屏核心类,这里直接看
KeyguardViewMediator类的处理。
@Override
public void startedGoingToSleep(int why) {
if (DEBUG_WAKEUP) Slog.i(TAG, "Started going to sleep... (why=" + why + ")");
mGoingToSleep = true;
mRequestedOrGoingToSleep = true;
if (mKeyguardDelegate != null) {
mKeyguardDelegate.onStartedGoingToSleep(why);
}
}
3.5 KeyguardViewMediator
KeyguardViewMediator的onStartedGoingToSleep方法会根据息屏的方式进行判断如是否为超时,是否需要播放锁屏音等。最后调用StatusBarKeyguardViewManager通知开始息屏。
public void onStartedGoingToSleep(int why) {
synchronized (this) {
mDeviceInteractive = false;
mGoingToSleep = true;
...
if (!mExternallyEnabled) {
hideLocked();
}
...
//判断是否需要播放锁屏音
if (mPendingLock) {
playSounds(true);
}
}
//通知开始息屏
notifyStartedGoingToSleep();
3.6 StatusBarKeyguardViewManager
开始息屏的方法onStartedGoingToSleep,只是设置标志,KeyguardBouncer的操作是在完成息屏的方法上。完成息屏行为的发出要回到PowerManagerService上。
public void onStartedGoingToSleep() {
mGoingToSleepVisibleNotOccluded = isShowing() && !isOccluded();
}
--------------------------
public void onFinishedGoingToSleep() {
mGoingToSleepVisibleNotOccluded = false;
mBouncer.onScreenTurnedOff();
}
3.7 PowerManagerService
在goToSleepInternal方法中,updatePowerStateLocked是更新电源状态的方法。
private void goToSleepInternal(long eventTime, int reason, int flags, int uid) {
synchronized (mLock) {
if (goToSleepNoUpdateLocked(eventTime, reason, flags, uid)) {
updatePowerStateLocked();
}
}
}
在updatePowerStateLocked方法内调用了finishWakefulnessChangeIfNeededLocked方法,而这个方法根据条件触发了Notifier的onWakefulnessChangeFinished。
private void updatePowerStateLocked() {
...
// Phase 5: Send notifications, if needed.
finishWakefulnessChangeIfNeededLocked();
}
}
private void finishWakefulnessChangeIfNeededLocked() {
if (mWakefulnessChanging && mDisplayReady) {
if (mWakefulness == WAKEFULNESS_DOZING
&& (mWakeLockSummary & WAKE_LOCK_DOZE) == 0) {
return; // wait until dream has enabled dozing
}
mNotifier.onWakefulnessChangeFinished();
}
}
3.8 Notifier
Notifier的onWakefulnessChangeFinished方法经过内部的调用最后会走到handleLateInteractiveChange方法上,方法内部调用了PhoneWindowManager的finishedGoingToSleep方法。
private void handleLateInteractiveChange() {
synchronized (mLock) {
if (mInteractive) {
mHandler.post(new Runnable() {
@Override
public void run() {
mPolicy.finishedWakingUp();
}
});
} else {
mHandler.post(new Runnable() {
@Override
public void run() {
//完成息屏
mPolicy.finishedGoingToSleep(why);
}
});
}
}
}
3.9 PhoneWindowManager
finishedGoingToSleep方法经过KeyguardServiceDelegate最终会调用KeyguardViewMediator锁屏核心类。
public void finishedGoingToSleep(int why) {
if (mKeyguardDelegate != null) {
mKeyguardDelegate.onFinishedGoingToSleep(why,
mCameraGestureTriggeredDuringGoingToSleep);
}
}
3.10 KeyguardViewMediator
KeyguardViewMediator的onFinishedGoingToSleep方法会重置锁屏状态和重新处理doKeyguardLocked的流程。
doKeyguardLocked方法会调用showLocked方法进行锁屏展示。这和锁屏开机的流程大致相同,只是息屏的时候会先重置状态,等待亮屏时使用。
public void onFinishedGoingToSleep(int why, boolean cameraGestureTriggered) {
synchronized (this) {
//重置锁屏状态
resetKeyguardDonePendingLocked();
//通知息屏完成
notifyFinishedGoingToSleep();
//重置锁屏状态
if (mPendingReset) {
resetStateLocked();
mPendingReset = false;
}
//重新处理锁屏View
if (mPendingLock) {
doKeyguardLocked(null);
mPendingLock = false;
}
}
}
四、亮屏分析
亮屏的处理也是从PowerManager开始,最终到锁屏的核心类KeyguardViewMediator,亮屏处理的大致流程如下:
4.1 PowerManager
按power键息屏会调用powerManager的wakeUp方法,而powerManager的处理是PowerManagerService类,所以是远程调用了PowerManagerService的wakeUp。
public void wakeUp(long time) {
try {
mService.wakeUp(time, "wakeUp", mContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
4.2 PowerManagerService
wakeUp方法主要调用了wakeUpInternal。
public void wakeUp(long eventTime, String reason, String opPackageName) {
try {
//主要调用
wakeUpInternal(eventTime, reason, uid, opPackageName, uid);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
在wakeUpInternal方法中,主要看updatePowerStateLocked这个方法。
private void wakeUpInternal(long eventTime, String reason, int uid, String opPackageName,
int opUid) {
synchronized (mLock) {
if (wakeUpNoUpdateLocked(eventTime, reason, uid, opPackageName, opUid)) {
//更新状态
updatePowerStateLocked();
}
}
}
在updatePowerStateLocked方法内调用了更新显示电源状态的方法。在updateDisplayPowerStateLocked方法内远程调用DisplayManagerService请求电源状态。
private boolean updateDisplayPowerStateLocked(int dirty) {
if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE) {
//远程调用DisplayManagerService
mDisplayReady = mDisplayManagerInternal.requestPowerState(mDisplayPowerRequest,
mRequestWaitForNegativeProximity);
...
return mDisplayReady && !oldDisplayReady;
}
4.3 DisplayManagerService
requestPowerState方法由接着调用DisplayPowerController。
@Override
public boolean requestPowerState(DisplayPowerRequest request,
boolean waitForNegativeProximity) {
synchronized (mSyncRoot) {
return mDisplayPowerController.requestPowerState(request,
waitForNegativeProximity);
}
}
4.4 DisplayPowerController
在DisplayPowerController类的requestPowerState方法内主要发送更新电源状态的消息,消息的处理是在updatePowerState这个方法。updatePowerState这个方法处理比较复杂,不过会先后调用到PhoneWindowManager的screenTurningOn和screenTurnedOn。
private boolean setScreenState(int state, boolean reportOnly){
...
//开始亮屏
mWindowManagerPolicy.screenTurningOn(mPendingScreenOnUnblocker);
...
}
private void updatePowerState() {
...
//亮屏完成
mWindowManagerPolicy.screenTurnedOn();
...
}
4.5 PhoneWindowManager
PhoneWindowManager的screenTurningOn方法又调用了KeyguardServiceDelegate。
@Override
public void screenTurningOn(final ScreenOnListener screenOnListener) {
...
mKeyguardDelegate.onScreenTurningOn(mKeyguardDrawnCallback);
...
}
4.6 KeyguardServiceDelegate
onScreenTurningOn方法则经过KeyguardService最后回到锁屏核心类KeyguardViewMediator。
public void onScreenTurningOn(final DrawnListener drawnListener) {
if (mKeyguardService != null) {
mKeyguardService.onScreenTurningOn(new KeyguardShowDelegate(drawnListener));
}
}
4.7 KeyguardViewMediator
KeyguardViewMediator的onScreenTurningOn会发送消息,处理消息回到handleNotifyScreenTurningOn中。
public void onScreenTurningOn(IKeyguardDrawnCallback callback) {
//发送消息
notifyScreenOn(callback);
}
handleNotifyScreenTurningOn方法主要调用StatusBarKeyguardViewManager和进行通知绘制。
private void handleNotifyScreenTurningOn(IKeyguardDrawnCallback callback) {
synchronized (KeyguardViewMediator.this) {
if (DEBUG) Log.d(TAG, "handleNotifyScreenTurningOn");
mStatusBarKeyguardViewManager.onScreenTurningOn();
if (callback != null) {
if (mWakeAndUnlocking) {
mDrawnCallback = callback;
} else {
notifyDrawn(callback);
}
}
}
Trace.endSection();
}
开始亮屏ScreenTurningOn的大致流程到这里基本完成,screenTurnedOn的流程和ScreenTurningOn基本相同。
参考