第五章:DisplayManagerService

简述

DisplayManagerService用来管理显示的生命周期,它决定如何根据当前连接的物理显示设备控制其逻辑显示,并且在状态更改时,向系统和应用程序发送通知,等等。一次多种显示类型的多显示器镜像显示,包括内建的显示类型(本地)、HDMI显示类型以及支持WIFI Display协议(MIRACAST),实现本地设备在远程显示器的镜像显示;

DisplayAdapterDisplayManagerService所依赖的集合组件,其为系统显示,收集并发现物理显示设备提供了适配器的作用。
目前有以下两种方式的适配器供使用

  • 一、为本地显示设备提供适配器。
  • 二、为开发者提供的模拟显示适配器。

DisplayAdapterDisplayManagerService 是弱耦合关系。DisplayAdapter通过注册在 DisplayManagerService类中的 DisplayAdapter.Listener 实现异步通信。

这样做有两个原因

  • 一、巧妙地封装了这两个类的职责,
    DisplayAdapter :处理各个显示设备
    DisplayManagerService:处理全局显示状态。
  • 二、消除异步显示设备发现导致死锁的可能性

Synchronization(同步锁)
因为显示管理器可能被多个线程访问,所以同步锁就会变得有点复杂。 特别是当窗口管理器( window manager)在保持绘制事务的同时调用显示管理器(display manager),窗口管理器期望它可以立即应用并更改。 但不幸的是,显示管理器(display manager)不能异步地做所有事情。
为了解决这个问题,显示管理器的所有对象必须持有相同的锁。 我们将此锁称为同步锁,它具有唯一性。

通过DisplayManager提供对外接口
提供接口包括如下:

  • 1.getDisplay(int displayId)根据displayId参数获得一个逻辑显示器的信息
  • 2.getDisplays()获得当前所有有效的逻辑显示器列表
  • 3.registerDisplayListener()登记一个显示监听对象,用来监听显示器的新增、去除或改变通知事件。
  • 4.unregisterDisplayListener()取消先前登记的一个显示监听对象
  • 5.createVirtualDisplay()创建一个虚拟显示器,虚拟显示的内容被渲染到提供的Surface中,当进程终止时虚拟显示器会被自动的释放,并且所有的Window都会被强制移除。当不再使用他时,你应该调用release()方法来释放资源。

相关类

  • 1.DisplayPowerController 控制屏幕显示相关的电源状态,包括距离传感器和光线传感器等。
  • 2.DisplayPowerState控制显示状态。当属性改变的时候,该组件以统一的顺序发生一个回调以应用这些改变。

一、初始化

跟其他系统服务一样, DisplayManagerService也是继承于SystemService并通过SystemServer启动。

frameworks/base/services/java/com/android/server/SystemServer.java

public final class SystemServer {
    private void startBootstrapServices() {
      ......
       mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
       ......
    }
}

DisplayManagerService继承 SystemService, 由 SystemServer 启动。
构造函数

public final class DisplayManagerService extends SystemService {
   ... 
    public DisplayManagerService(Context context) {
        this(context, new Injector());
    }

    @VisibleForTesting
    DisplayManagerService(Context context, Injector injector) {
        super(context);
        mInjector = injector;
        mContext = context;
      //Step:1
        mHandler = new DisplayManagerHandler(DisplayThread.get().getLooper());
        mUiHandler = UiThread.getHandler();
    //Step:2
        mDisplayAdapterListener = new DisplayAdapterListener();
//Step:3
        mSingleDisplayDemoMode = SystemProperties.getBoolean("persist.demo.singledisplay", false);
        mDefaultDisplayDefaultColorMode = mContext.getResources().getInteger(
com.android.internal.R.integer.config_defaultDisplayDefaultColorMode);
//Step:4
        PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
        mGlobalDisplayBrightness = pm.getDefaultScreenBrightnessSetting();
    }
    ...
}
  • 1.创建Handler接收消息并处理
  • 2.创建适配器监听器,用于监听设备的添加、改变、异常
  • 3.用于开发模式
  • 4.获取电源管理

onStart方法

   @Override
    public void onStart() {
        //Step 1
        mPersistentDataStore.loadIfNeeded();
       //Step 2
mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER);
   //Step 3
        publishBinderService(Context.DISPLAY_SERVICE, new BinderService(),
                true /*allowIsolated*/);
   //Step 4
        publishLocalService(DisplayManagerInternal.class, new LocalService());
   //Step 5
        publishLocalService(DisplayTransformManager.class, new DisplayTransformManager());
    }
    1. 加载本地持久化数据
  • 2.发送消息注册默认适配器
  • 3.对其他services或者app应用公开BinderServiceAIDL远程服务
  • 4.对系统进程公开LocalServiceDisplayTransformManager

加载本地持久数据
/frameworks/base/services/core/java/com/android/server/display/PersistentDataStore.java

 public void loadIfNeeded() {
        if (!mLoaded) {
            load();
            mLoaded = true;
        }
    }
   private void load() {
        clearState();

        final InputStream is;
        try {
            is = mAtomicFile.openRead();
        } catch (FileNotFoundException ex) {
            return;
        }
        XmlPullParser parser;
        try {
            parser = Xml.newPullParser();
            parser.setInput(new BufferedInputStream(is), StandardCharsets.UTF_8.name());
            loadFromXml(parser);
        } catch (IOException ex) {
            Slog.w(TAG, "Failed to load display manager persistent store data.", ex);
            clearState();
        } catch (XmlPullParserException ex) {
            Slog.w(TAG, "Failed to load display manager persistent store data.", ex);
            clearState();
        } finally {
            IoUtils.closeQuietly(is);
        }
    }

注册默认显示器
主要功能是将显示设备添加注册到mDisplayAdapters集合中

 private void registerDefaultDisplayAdapter() {
        // Register default display adapter.
        synchronized (mSyncRoot) {
            registerDisplayAdapterLocked(new LocalDisplayAdapter(
                    mSyncRoot, mContext, mHandler, mDisplayAdapterListener));
        }
    }
 private void registerDisplayAdapterLocked(DisplayAdapter adapter) {
        mDisplayAdapters.add(adapter);
        adapter.registerLocked();
    }

onBootPhase()方法
等待默认显示器

 @Override
    public void onBootPhase(int phase) {
        if (phase == PHASE_WAIT_FOR_DEFAULT_DISPLAY) {
            synchronized (mSyncRoot) {
                long timeout = SystemClock.uptimeMillis() + WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT;
                while (mLogicalDisplays.get(Display.DEFAULT_DISPLAY) == null) {
               ......
                    try {
                        mSyncRoot.wait(delay);
                    } catch (InterruptedException ex) {
                    }
                }
            }
        }
    }

systemReady()方法
服务就绪

public void systemReady(boolean safeMode, boolean onlyCore) {
        synchronized (mSyncRoot) {
            mSafeMode = safeMode;
            mOnlyCore = onlyCore;
        }
//注册调价适配器类型
mHandler.sendEmptyMessage(MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS);
    }

    private void registerAdditionalDisplayAdapters() {
        synchronized (mSyncRoot) {
            if (shouldRegisterNonEssentialDisplayAdaptersLocked()) {
              //开发模式用
                registerOverlayDisplayAdapterLocked();
              //wifi 远程显示器用
                registerWifiDisplayAdapterLocked();
              //虚拟显示用
                registerVirtualDisplayAdapterLocked();
            }
        }
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,504评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,434评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,089评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,378评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,472评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,506评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,519评论 3 413
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,292评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,738评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,022评论 2 329
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,194评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,873评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,536评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,162评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,413评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,075评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,080评论 2 352