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.
    @Override
    public 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.
    @Override
    public 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;
        }

        @Override
        public void acquire(int displayId) {
            synchronized (mGlobalLock) {
                if (!mSleepTokens.contains(displayId)) {
                    mSleepTokens.append(displayId,
                            mRootWindowContainer.createSleepToken(mTag, displayId));
                            
                    //调用ActivityTaskManagerService的updateSleepIfNeededLocked方法对resume的Activity进行pause        
                    updateSleepIfNeededLocked();
                }
            }
        }

        @Override
        public 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);
        }

        @Override
        public String toString() {
            return "{\"" + mTag + "\", display " + mDisplayId
                    + ", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
        }
    }

SleepToken机制

相关推荐
2501_9462447841 分钟前
Flutter & OpenHarmony OA系统图片预览组件开发指南
android·javascript·flutter
极客小云1 小时前
【IEEE Transactions系列期刊全览:计算机领域核心期刊深度解析】
android·论文阅读·python
wanghowie1 小时前
02.01 Spring Boot|自动配置机制深度解析
android·spring boot·后端
一起搞IT吧1 小时前
三方相机问题分析十一:【手电筒回调异常】手电筒打开3档时,达到档位控制温度,手电筒二级界面中档位为0
android·图像处理·数码相机
2501_924064111 小时前
2025年移动应用渗透测试流程方案及iOS安卓测试方法对比
android·ios
千里马学框架1 小时前
安卓14-16车机手机仿小米su7三分屏实战项目专题
android·智能手机·framework·分屏·车载·小米汽车·三分屏
走在路上的菜鸟2 小时前
Android学Flutter学习笔记 第二节 Android视角认知Flutter(resource,生命周期,layout)
android·学习·flutter
zh_xuan2 小时前
kotlin的常见空检查
android·开发语言·kotlin
踏雪羽翼11 小时前
android TextView实现文字字符不同方向显示
android·自定义view·textview方向·文字方向·textview文字显示方向·文字旋转·textview文字旋转
lxysbly11 小时前
安卓玩MRP冒泡游戏:模拟器下载与使用方法
android·游戏