Android ScreenSaver分析

基于Android9.0(API Level:  28)源码分析。

涉及代码:

 /frameworks/base/services/core/java/com/android/server/dreams/DreamManagerService.java

 /frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java

 /frameworks/base/services/core/java/com/android/server/dreams/DreamController.java

 /frameworks/base/core/java/android/service/dreams/DreamService.java

/packages/apps/DeskClock/src/com/android/deskclock/Screensaver.java   // 系统默认屏保service

Android屏保是什么?

        可能我们从屏保画面来看会认为屏保是一个activity,但是实际上屏保画面显示是通过service显示的。屏保启动时会bind屏保service(DreamService),然后在service上创建PhoneWindow显示在画面上。具体可以用实机验证。当屏保显示时,通过adb去dumpsys window看看屏保是不是activity。

Android屏保启动方式

一、主动启动屏保。

IDreamManager mDreamManager = IDreamManager.Stub.asInterface(ServiceManager.getService(DreamService.DREAM_SERVICE));
/** @hide */
interface IDreamManager {
    void dream();  // 启动屏保
    void awaken();  // 唤醒屏幕,即关闭屏保
    void setDreamComponents(in ComponentName[] componentNames); // 设置屏保组件 service
    ComponentName[] getDreamComponents();  
    ComponentName getDefaultDreamComponent();
    void testDream(in ComponentName componentName);
    boolean isDreaming();
    void finishSelf(in IBinder token, boolean immediate);
    void startDozing(in IBinder token, int screenState, int screenBrightness);
    void stopDozing(in IBinder token);
}

我们如果不设置自定义屏保,则系统会使用默认屏保。

实际处理屏保的逻辑在DreamManagerService中,当调用IDreamManager的dream()接口时会走到DreamManagerService类中。

获取屏保接口涉及bind调用,对应的service在系统启动时就已经注册过了,具体注册过程:

从上述时序图2.2中会发现我们通过bind获取的mDreamManager 实际上是BinderService。我们调用dream函数时,屏保启动过程:

mDreamManager.dream()

——>PowerManagerService.nap()

——>PowerManagerService.updatePowerStateLocked()

——>PowerManagerService.canDreamLocked(){判断是否要启动屏保,其中会去读取config.xml文件,确认屏保是否支持、屏保是否打开}

——>LocalService.startDream(boolean){DreamManagerService的内部类}

——>DreamController.startDream()

——>binderService{绑定DreamService,系统屏保/自定义屏保都继承该service}

二、系统电源状态变化时启动,比如充电时、低电量等。

        电源变化时PowManagerService中的updatePowerStateLocked函数会被调用,对应上述时序图中的5.1.1.1.1。

Android屏保画面

一、系统默认屏保

        系统默认屏保是Screensaver,该类继承DreamService。

二、自定义屏保

  1. 首先创建一个service继承DreamService,在onAttachToWindow函数中设置自定义layout。
  2. 然后调用setDreamComponents(in ComponentName[] componentNames);接口将该service作为ComponentName对象参数传入。
  3. 调用dream()启动屏保。

Android屏保开关

在PowManagerService中的updatePowerStateLocked函数会调用canDreamLocked来判断是否应该启动屏保,该函数中会读取配置文件:

/frameworks/base/core/res/res/values/config.xml

<bool name="config_dreamsSupported">true</bool>    // 是否支持屏保,如果设置false,则屏保功能无法打开。
<bool name="config_dreamsEnabledByDefault">true</bool>  // 屏保开关,如果设置false,可以通过设定项主动打开。
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值