本文主要是介绍Android 11 About SleepToken / (Settings)Screen timeout,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Android R 激活Settings里面的息屏休眠, 最前台运行的Activity生命周期 ->onPause->onStop
adb shell dumpsys window policy //获取PhoneWindowManager的dump信息...
bootCompleted=true
screenState=SCREEN_STATE_ON /SCREEN_STATE_OFF
interactiveState=INTERACTIVE_STATE_AWAKE /INTERACTIVE_STATE_SLEEP
...
case A.不使用屏保
当设备超过设定的时间后,进入SCREEN_STATE_OFF状态,最前台运行的Activity生命周期 ->onPause->onStop.
那到底是谁让Activity进入了onStop状态?
跟踪代码发现:
/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java// Called on the DisplayManager's DisplayPowerController thread.@Overridepublic void screenTurnedOff() {if (DEBUG_WAKEUP) Slog.i(TAG, "Screen turned off...");updateScreenOffSleepToken(true);mDefaultDisplayPolicy.screenTurnedOff();synchronized (mLock) {if (mKeyguardDelegate != null) {mKeyguardDelegate.onScreenTurnedOff();}}mDefaultDisplayRotation.updateOrientationListener();reportScreenStateToVrManager(false);}// Called on the DisplayManager's DisplayPowerController thread.@Overridepublic void screenTurningOn(final ScreenOnListener screenOnListener) {if (DEBUG_WAKEUP) Slog.i(TAG, "Screen turning on...");Trace.asyncTraceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "screenTurningOn", 0 /* cookie */);updateScreenOffSleepToken(false);mDefaultDisplayPolicy.screenTurnedOn(screenOnListener);...} //SCREEN_STATE_OFF 时调用screenTurnedOff(..),这个函数里面有updateScreenOffSleepToken(true)// TODO (multidisplay): Support multiple displays in WindowManagerPolicy.private void updateScreenOffSleepToken(boolean acquire) {if (acquire) {mScreenOffSleepTokenAcquirer.acquire(DEFAULT_DISPLAY);} else {mScreenOffSleepTokenAcquirer.release(DEFAULT_DISPLAY);}}frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java//SleepTokenAcquirer是ActivityTaskManagerService的内部类final class SleepTokenAcquirerImpl implements ActivityTaskManagerInternal.SleepTokenAcquirer {private final String mTag;private final SparseArray<RootWindowContainer.SleepToken> mSleepTokens =new SparseArray<>();SleepTokenAcquirerImpl(@NonNull String tag) {mTag = tag;}@Overridepublic void acquire(int displayId) {synchronized (mGlobalLock) {if (!mSleepTokens.contains(displayId)) {mSleepTokens.append(displayId,mRootWindowContainer.createSleepToken(mTag, displayId));//调用ActivityTaskManagerService的updateSleepIfNeededLocked方法对resume的Activity进行pause updateSleepIfNeededLocked();}}}@Overridepublic void release(int displayId) {synchronized (mGlobalLock) {final RootWindowContainer.SleepToken token = mSleepTokens.get(displayId);if (token != null) {mRootWindowContainer.removeSleepToken(token);mSleepTokens.remove(displayId);}}}}
1.(息屏)在获取了SleepToken后,会将resume的Activity进入pause状态.如下:
SleepTokenAcquirerImpl::acquire()
--->
RootWindowContainer::createSleepToken()->ActivityTaskManagerService::updateSleepIfNeededLocked()
--->
ActivityStackSupervisor::goingToSleepLocked()
--->
ActivityStackSupervisor::checkReadyForSleepLocked()
--->
RootWindowContainer::putStacksToSleep()
--->
ActivityStack::goToSleepIfPossible()
--->
ActivityStack::startPausingLocked()
2.(亮屏)在释放了SleepToken后,如果此时没有SleepToken了,并且也没有keyguard,会对前台Activity进行resume.
SleepTokenAcquirerImpl::release()
--->
RootWindowContainer::removeSleepToken()
--->
ActivityTaskManagerService::updateSleepIfNeededLocked()
--->
RootWindowContainer::applySleepTokens()
--->
ActivityStack::resumeTopActivityUncheckedLocked()
如果不想设备当前Activity被pause,如下:
+++ b/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -4708,7 +4708,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {public void screenTurnedOff() {if (DEBUG_WAKEUP) Slog.i(TAG, "Screen turned off...");- updateScreenOffSleepToken(true);
+ //updateScreenOffSleepToken(true);mDefaultDisplayPolicy.screenTurnedOff();synchronized (mLock) {
cast B.使用屏保(com.android.deskclock/android.service.dreams.DreamActivity)
前台Activity —>App A
com.android.deskclock/android.service.dreams.DreamActivity —> App B
App A 被 App B 挤下去了,当前App A不在栈顶(前台)时,App A就会执行on Pause流程
SleepToken
frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
//SleepToken是RootWindowContainer的内部类static final class SleepToken {private final String mTag;private final long mAcquireTime;private final int mDisplayId;final int mHashKey;SleepToken(String tag, int displayId) {mTag = tag;mDisplayId = displayId;mAcquireTime = SystemClock.uptimeMillis();mHashKey = makeSleepTokenKey(mTag, mDisplayId);}@Overridepublic String toString() {return "{\"" + mTag + "\", display " + mDisplayId+ ", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";}}
SleepToken机制
这篇关于Android 11 About SleepToken / (Settings)Screen timeout的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!