1.PowerManagerService和PhoneWindowMangerService主要调用了Keyguard的onStartedGoingToSleep和onFinishedGoingToSleep
@/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java#6676
public void init(Context context, IWindowManager windowManager,
2127 if (!mPowerManager.isInteractive()) {
2128 startedGoingToSleep(WindowManagerPolicy.OFF_BECAUSE_OF_USER);
2129 finishedGoingToSleep(WindowManagerPolicy.OFF_BECAUSE_OF_USER);
2130 }
@@frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
@Override // Binder call
public void wakeUp(long eventTime, String reason, String opPackageName) {
if (eventTime > SystemClock.uptimeMillis()) {
throw new IllegalArgumentException("event time must not be in the future");
}
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.DEVICE_POWER, null);
final int uid = Binder.getCallingUid();
final long ident = Binder.clearCallingIdentity();
try {
wakeUpInternal(eventTime, reason, uid, opPackageName, uid);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
private void wakeUpInternal(long eventTime, String reason, int uid, String opPackageName,
int opUid) {
synchronized (mLock) {
if (wakeUpNoUpdateLocked(eventTime, reason, uid, opPackageName, opUid)) {
updatePowerStateLocked();
}
}
}
private boolean wakeUpNoUpdateLocked(long eventTime, String reason, int reasonUid,
String opPackageName, int opUid) {
if (DEBUG_SPEW) {
Slog.d(TAG, "wakeUpNoUpdateLocked: eventTime=" + eventTime + ", uid=" + reasonUid);
}
Trace.traceBegin(Trace.TRACE_TAG_POWER, "wakeUp");
try {
switch (mWakefulness) {
case WAKEFULNESS_ASLEEP:
Slog.i(TAG, "Waking up from sleep (uid " + reasonUid +")...");
break;
case WAKEFULNESS_DREAMING:
Slog.i(TAG, "Waking up from dream (uid " + reasonUid +")..."); //熟悉的Log
break;
case WAKEFULNESS_DOZING:
Slog.i(TAG, "Waking up from dozing (uid " + reasonUid +")...");
break;
}
mLastWakeTime = eventTime;
setWakefulnessLocked(WAKEFULNESS_AWAKE, 0);
mNotifier.onWakeUp(reason, reasonUid, opPackageName, opUid);
userActivityNoUpdateLocked(
eventTime, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, reasonUid);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER);
}
return true;
}
@frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
private void setWakefulnessLocked(int wakefulness, int reason) {
if (mWakefulness != wakefulness) {
mWakefulness = wakefulness;
mWakefulnessChanging = true;
mDirty |= DIRTY_WAKEFULNESS;
mNotifier.onWakefulnessChangeStarted(wakefulness, reason);
}
}
340 public void onWakefulnessChangeStarted(final int wakefulness, int reason) {
341 final boolean interactive = PowerManagerInternal.isInteractive(wakefulness);
342 if (DEBUG) {
343 Slog.d(TAG, "onWakefulnessChangeStarted: wakefulness=" + wakefulness
344 + ", reason=" + reason + ", interactive=" + interactive);
345 }
...
377 handleEarlyInteractiveChange();
378 }
379 }
9 private void 9 private void handleEarlyInteractiveChange() {
400 synchronized (mLock) {
401 if (mInteractive) {
402 // Waking up...
403 mHandler.post(new Runnable() {
404 @Override
405 public void run() {
406 // Note a SCREEN tron event is logged in PowerManagerService.
407 mPolicy.startedWakingUp();
408 }
409 });
410
411 // Send interactive broadcast.
412 mPendingInteractiveState = INTERACTIVE_STATE_AWAKE;
413 mPendingWakeUpBroadcast = true;
414 updatePendingBroadcastLocked();
415 } else {
416 // Going to sleep...
417 // Tell the policy that we started going to sleep.
418 final int why = translateOffReason(mInteractiveChangeReason);
419 mHandler.post(new Runnable() {
420 @Override
421 public void run() {
422 mPolicy.startedGoingToSleep(why);
423 }
424 });
425 }
426 }
427 }() {
400 synchronized (mLock) {
401 if (mInteractive) {
402 // Waking up...
403 mHandler.post(new Runnable() {
404 @Override
405 public void run() {
406 // Note a SCREEN tron event is logged in PowerManagerService.
407 mPolicy.startedWakingUp();
408 }
409 });
410
411 // Send interactive broadcast.
412 mPendingInteractiveState = INTERACTIVE_STATE_AWAKE;
413 mPendingWakeUpBroadcast = true;
414 updatePendingBroadcastLocked();
415 } else {
416 // Going to sleep...
417 // Tell the policy that we started going to sleep.
418 final int why = translateOffReason(mInteractiveChangeReason);
419 mHandler.post(new Runnable() {
420 @Override
421 public void run() {
422 mPolicy.startedGoingToSleep(why);
423 }
424 });
425 }
426 }
427 }
// Called on the PowerManager's Notifier thread.
@Override
public void startedGoingToSleep(int why) {
if (DEBUG_WAKEUP) Slog.i(TAG, "Started going to sleep... (why=" + why + ")");
mCameraGestureTriggeredDuringGoingToSleep = false;
mGoingToSleep = true;
if (mKeyguardDelegate != null) {
mKeyguardDelegate.onStartedGoingToSleep(why);
}
}
//power key press -- goToSleep
1420 private void powerPress(long eventTime, boolean interactive, int count) {
1421 if (mScreenOnEarly && !mScreenOnFully) {
1422 Slog.i(TAG, "Suppressed redundant power key press while "
1423 + "already in the process of turning the screen on.");
1424 return;
1425 }
1431 } else if (interactive && !mBeganFromNonInteractive) {
1432 switch (mShortPressOnPowerBehavior) {
1433 case SHORT_PRESS_POWER_NOTHING:
1434 break;
1435 case SHORT_PRESS_POWER_GO_TO_SLEEP:
1436 goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0);
1437 break;
1438 case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP:
1439 goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,
1440 PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
1441 break;
1442 case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP_AND_GO_HOME:
1443 goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,
1444 PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
1445 launchHomeFromHotKey();
1446 break;
...
1464 }
1465 }
1466 }
1468 private void goToSleep(long eventTime, int reason, int flags) {
1469 mRequestedOrGoingToSleep = true;
1470 mPowerManager.goToSleep(eventTime, reason, flags);
1471 }
2.KeyguardViewMediator
@frameworks/base/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
public void onStartedGoingToSleep(int why) {
if (DEBUG) Log.d(TAG, "onStartedGoingToSleep(" + why + ")"); //why power灭屏是2
synchronized (this) {
mDeviceInteractive = false;
mGoingToSleep = true;
// Lock immediately based on setting if secure (user has a pin/pattern/password).
// This also "locks" the device when not secure to provide easy access to the
// camera while preventing unwanted input.
int currentUser = KeyguardUpdateMonitor.getCurrentUser();
final boolean lockImmediately =
mLockPatternUtils.getPowerButtonInstantlyLocks(currentUser)
|| !mLockPatternUtils.isSecure(currentUser); //lockImmediately就是设置里面的即时锁屏开关
long timeout = getLockTimeout(KeyguardUpdateMonitor.getCurrentUser());
mLockLater = false;
if (mExitSecureCallback != null) {
if (DEBUG) Log.d(TAG, "pending exit secure callback cancelled");
try {
mExitSecureCallback.onKeyguardExitResult(false);
} catch (RemoteException e) {
Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e);
}
mExitSecureCallback = null;
if (!mExternallyEnabled) {
hideLocked();
}
} else if (mShowing) {
mPendingReset = true; //有个异常走这里,因为指纹模式改为WAKE_UNLOCK导致
} else if ((why == WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT && timeout > 0)
|| (why == WindowManagerPolicy.OFF_BECAUSE_OF_USER && !lockImmediately)) {
doKeyguardLaterLocked(timeout);
mLockLater = true;
} else if (!mLockPatternUtils.isLockScreenDisabled(currentUser)) {
mPendingLock = true; //正常走这里mPendingLock
}
if (mPendingLock) {
playSounds(true); //然后播放声音
}
}
KeyguardUpdateMonitor.getInstance(mContext).dispatchStartedGoingToSleep(why);
notifyStartedGoingToSleep(); //notifyStartedGoingToSleep
}
public void onFinishedGoingToSleep(int why, boolean cameraGestureTriggered) {
if (DEBUG) Log.d(TAG, "onFinishedGoingToSleep(" + why + ")");
synchronized (this) {
mDeviceInteractive = false;
mGoingToSleep = false;
resetKeyguardDonePendingLocked();
mHideAnimationRun = false;
notifyFinishedGoingToSleep(); //notify finish
if (cameraGestureTriggered) {
Log.i(TAG, "Camera gesture was triggered, preventing Keyguard locking.");
// Just to make sure, make sure the device is awake.
mContext.getSystemService(PowerManager.class).wakeUp(SystemClock.uptimeMillis(),
"com.android.systemui:CAMERA_GESTURE_PREVENT_LOCK");
mPendingLock = false;
mPendingReset = false;
}
if (mPendingReset) {
resetStateLocked();
mPendingReset = false;
}
if (mPendingLock) {
doKeyguardLocked(null); //正常走这里
mPendingLock = false;
}
// We do not have timeout and power button instant lock setting for profile lock.
// So we use the personal setting if there is any. But if there is no device
// we need to make sure we lock it immediately when the screen is off.
if (!mLockLater && !cameraGestureTriggered) {
doKeyguardForChildProfilesLocked();
}
}
KeyguardUpdateMonitor.getInstance(mContext).dispatchFinishedGoingToSleep(why);
}
/**
* Enable the keyguard if the settings are appropriate.
*/
private void doKeyguardLocked(Bundle options) {
// if another app is disabling us, don't show
if (!mExternallyEnabled) {
if (DEBUG) Log.d(TAG, "doKeyguard: not showing because externally disabled");
// note: we *should* set mNeedToReshowWhenReenabled=true here, but that makes
// for an occasional ugly flicker in this situation:
// 1) receive a call with the screen on (no keyguard) or make a call
// 2) screen times out
// 3) user hits key to turn screen back on
// instead, we reenable the keyguard when we know the screen is off and the call
// ends (see the broadcast receiver below)
// TODO: clean this up when we have better support at the window manager level
// for apps that wish to be on top of the keyguard
return;
}
// if the keyguard is already showing, don't bother
if (mStatusBarKeyguardViewManager.isShowing()) {
if (DEBUG) Log.d(TAG, "doKeyguard: not showing because it is already showing");
resetStateLocked();
return;
}
// In split system user mode, we never unlock system user.
if (!mustNotUnlockCurrentUser()
|| !mUpdateMonitor.isDeviceProvisioned()) {
// if the setup wizard hasn't run yet, don't show
final boolean requireSim = !SystemProperties.getBoolean("keyguard.no_require_sim", false);
final boolean absent = SubscriptionManager.isValidSubscriptionId(
mUpdateMonitor.getNextSubIdForState(ABSENT));
final boolean disabled = SubscriptionManager.isValidSubscriptionId(
mUpdateMonitor.getNextSubIdForState(IccCardConstants.State.PERM_DISABLED));
final boolean lockedOrMissing = mUpdateMonitor.isSimPinSecure()
|| ((absent || disabled) && requireSim);
if (!lockedOrMissing && shouldWaitForProvisioning()) {
if (DEBUG) Log.d(TAG, "doKeyguard: not showing because device isn't provisioned"
+ " and the sim is not locked or missing");
return;
}
boolean forceShow = options != null && options.getBoolean(OPTION_FORCE_SHOW, false);
if (mLockPatternUtils.isLockScreenDisabled(KeyguardUpdateMonitor.getCurrentUser())
&& !lockedOrMissing && !forceShow) {
if (DEBUG) Log.d(TAG, "doKeyguard: not showing because lockscreen is off");
return;
}
if (mLockPatternUtils.checkVoldPassword(KeyguardUpdateMonitor.getCurrentUser())) {
if (DEBUG) Log.d(TAG, "Not showing lock screen since just decrypted");
// Without this, settings is not enabled until the lock screen first appears
setShowingLocked(false);
hideLocked();
mUpdateMonitor.reportSuccessfulStrongAuthUnlockAttempt();
return;
}
}
if (DEBUG) Log.d(TAG, "doKeyguard: showing the lock screen");
showLocked(options); //showLocked
}
/**
* Handle message sent by {@link #showLocked}.
* @see #SHOW
*/
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);
mStatusBarKeyguardViewManager.show(options);
mHiding = false;
mWakeAndUnlocking = false;
resetKeyguardDonePendingLocked();
mHideAnimationRun = false;
adjustStatusBarLocked();
userActivity();
mShowKeyguardWakeLock.release();
}
mKeyguardDisplayManager.show(); //show
Trace.endSection();
}
startedGoingToSleep流程
PhoneWindowManager.java interceptPowerKeyUp -- powerPress--
PowerManagerService.java goToSleep -- goToSleepInternal -- goToSleepNoUpdateLocked -- setWakefulnessLocked
onWakefulnessChangeStarted --handleEarlyInteractiveChange --startedGoingToSleep
Notifier.java mPolicy.startedGoingToSleep
mPolicy.finishedGoingToSleep
Log流程:
Started going to sleep... (why=" + why + ")
onStartedGoingToSleep(" + why
playSounds
notifyStartedGoingToSleep
onFinishedGoingToSleep
doKeyguardLocked
doKeyguard: showing the lock screen
handleShow