美文网首页
第十二章:DreamManagerService

第十二章:DreamManagerService

作者: momxmo | 来源:发表于2020-04-14 11:42 被阅读0次

简介

DreamManagerService主要是提供屏保服务,应用可以通过继承DreamService实现自己想要的屏保效果,《自定义系统屏保DreamService》这篇文章介绍怎么自定义自己屏保,比如现在各个手机厂商定义很炫酷的充电动画!

屏保服务执行流程

image.png

涉及到代码

  • /frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java 显示屏保功能的入口
  • /frameworks/base/services/core/java/com/android/server/dreams/DreamManagerService.java 管理屏保APP
  • /frameworks/base/services/core/java/com/android/server/dreams/DreamController.java 屏保具体的呼起
  • /packages/apps/DeskClock/src/com/android/deskclock/Screensaver.java 闹钟模块默认的屏保

一、 初始化

跟其他系统服务一样,DreamManagerService也是继承于SystemService并通过SystemServer启动。
SystemServer启动DreamManagerService服务
frameworks/base/services/java/com/android/server/SystemServer.java

private void startOtherServices() {
  ......
 mSystemServiceManager.startService(DreamManagerService.class);
  ......
}

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

public final class DreamManagerService extends SystemService {
 public DreamManagerService(Context context) {
        super(context);
        mContext = context;
       //创建Handler处理消息
        mHandler = new DreamHandler(FgThread.get().getLooper());
       //创建屏保控制器,控制屏保的开启和关闭,并通过回调监听
        mController = new DreamController(context, mHandler, mControllerListener);

//获取电源管理的核心服务
        mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
        mPowerManagerInternal = getLocalService(PowerManagerInternal.class);
//创建WakeLock 用于控制设备的休眠和唤醒
        mDozeWakeLock = mPowerManager.newWakeLock(PowerManager.DOZE_WAKE_LOCK, TAG);
        mDozeConfig = new AmbientDisplayConfiguration(mContext);
    }
}

构造函数的工作主要:
1.创建Handler处理消息
2.创建屏保控制器,控制屏保的开启和关闭,并通过回调监听
3.获取电源管理的核心服务
4.创建WakeLock 用于控制设备的休眠和唤醒

二、启动服务

下面继续看DreamManagerService在系统启动过程中回调onStart(),onBootPhase(),systemReady()的实现。

 @Override
    public void onStart() {
        //注册DreamService服务
        publishBinderService(DreamService.DREAM_SERVICE, new BinderService());
       //注册本地服务
        publishLocalService(DreamManagerInternal.class, new LocalService());
    }
 @Override
    public void onBootPhase(int phase) {
        if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
            if (Build.IS_DEBUGGABLE) {
                SystemProperties.addChangeCallback(mSystemPropertiesChanged);
            }
            mContext.registerReceiver(new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    writePulseGestureEnabled();
                    synchronized (mLock) {
                        stopDreamLocked(false /*immediate*/);
                    }
                }
            }, new IntentFilter(Intent.ACTION_USER_SWITCHED), null, mHandler);
            mContext.getContentResolver().registerContentObserver(
                    Settings.Secure.getUriFor(Settings.Secure.DOZE_PULSE_ON_DOUBLE_TAP), false,
                    mDozeEnabledObserver, UserHandle.USER_ALL);
            writePulseGestureEnabled();
        }
    }

启动和关闭屏保
private void startDreamLocked(final ComponentName name,
            final boolean isTest, final boolean canDoze, final int userId) {
      //如果当前屏保和需要启动的屏保是同一个组件,直接退出
        if (Objects.equal(mCurrentDreamName, name)
                && mCurrentDreamIsTest == isTest
                && mCurrentDreamCanDoze == canDoze
                && mCurrentDreamUserId == userId) {
            Slog.i(TAG, "Already in target dream.");
            return;
        }
        //先关闭之前的屏保
        stopDreamLocked(true /*immediate*/);
       ..................
        PowerManager.WakeLock wakeLock = mPowerManager
                .newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "startDream");
        mHandler.post(wakeLock.wrap(
              //通过控制器创建并开启屏保
                () -> mController.startDream(newToken, name, isTest, canDoze, userId, wakeLock)));
    }

 private void stopDreamLocked(final boolean immediate) {
......
 mHandler.post(new Runnable() {
                @Override
                public void run() {
                    Slog.i(TAG, "Performing gentle wake from dream.");
                    //最终会去调用控制器停止屏保
                    mController.stopDream(immediate);
                }
            });
......
}

三、核心

DreamManagerService与自定义的DreamService服务通讯是通过DreamController.java控制器内部中的DreamRecord 服务连接对象实现的;
DreamRecord客户端 ----->ServiceConnection ---->自定义的DreamService屏保服务端
DreamService也是集成至Service服务的,所以是属于正常的服务组件

final class DreamController {
.........
  private final class DreamRecord implements DeathRecipient, ServiceConnection {
// 连接服务
        @Override
        public void onServiceConnected(ComponentName name, final IBinder service) {
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    mConnected = true;
                    if (mCurrentDream == DreamRecord.this && mService == null) {
                        attach(IDreamService.Stub.asInterface(service));
                        // Wake lock will be released once dreaming starts.
                    } else {
                        releaseWakeLockIfNeeded();
                    }
                }
            });
        }
 // 断开连接
        @Override
        public void onServiceDisconnected(ComponentName name) {
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    mService = null;
                    if (mCurrentDream == DreamRecord.this) {
                      //关闭屏保
                        stopDream(true /*immediate*/);
                    }
                }
            });
        }
//释放锁来恢复休眠机制
 void releaseWakeLockIfNeeded() {
            if (mWakeLock != null) {
                mWakeLock.release();
                mWakeLock = null;
                mHandler.removeCallbacks(mReleaseWakeLockIfNeeded);
            }
        }
}
.........
}

相关文章

网友评论

      本文标题:第十二章:DreamManagerService

      本文链接:https://www.haomeiwen.com/subject/jqlzmhtx.html