DisplayManagerService(一)

DisplayManagerService(一),第1张

概述极力推荐Android 开发大总结文章:欢迎收藏 程序员Android 力荐 ,Android 开发者需要的必备技能 本篇文章主要介绍 Android 开发中的部分知识点,通过阅读本篇文章,您将收获以下内容: 1.DisplayManagerService的启动 2.DisplayManagerService 作用 3.DisplayManagerService 继承关系 4.DisplayMan

极力推荐AndroID 开发大总结文章:欢迎收藏
程序员Android 力荐 ,Android 开发者需要的必备技能

本篇文章主要介绍 AndroID 开发中的部分知识点,通过阅读本篇文章,您将收获以下内容:

1.displayManagerService的启动
2.displayManagerService 作用
3.displayManagerService 继承关系
4.displayManagerService 的构造方法
5.displayManagerService 的onStart 方法
6.displayManagerService 的onBootPhase(int phase) 方法

前言
本文涉及代码类路径如下,后续涉及代码内容,请参考以下目录。

frameworks\base\services\java\com\androID\server\SystemServer.javaframeworks\base\services\core\java\com\androID\server\display\displayManagerService.java
1.displayManagerService的启动

displayManagerService 是有 SystemServer
startbootstrapServices 引导阶段中通过startService启动,代码如下:

public final class SystemServer {    ...    private voID startbootstrapServices() {        ...        // display manager is needed to provIDe display metrics before package manager        // starts up.        traceBeginAndSlog("StartdisplayManager");        //1.启动 displayManagerService        mdisplayManagerService = mSystemServiceManager.startService(displayManagerService.class);        traceEnd();        ...     }    ...}
2.displayManagerService 作用

displayManagerService 用来管理显示的生命周期,它决定如何根据当前连接的物理显示设备控制其逻辑显示,并且在状态更改时,向系统和应用程序发送通知,等等。

displayAdapter 是 displayManagerService 所依赖的集合组件,其为系统显示,收集并发现物理显示设备提供了适配器的作用。
目前有以下两种方式的适配器供使用
一、为本地显示设备提供适配器。
二、为开发者提供的模拟显示适配器。

displayAdapter 与 displayManagerService 是弱耦合关系。displayAdapter通过注册在 displayManagerService类中的 displayAdapter.Listener 实现异步通信。

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

Synchronization(同步锁)

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

3.displayManagerService 继承关系

displayManagerService继承 SystemService,由 SystemServer 启动。

public final class displayManagerService extends SystemService {   ... }

SystemService 是系统Service的基类,相关类使用要重写它的以下生命周期方法(构造方法、onStart() 、onBootPhase(int)),并且所有生命周期内地方法都可以被 system server主线程循环调用。
构造方法
在系统 初始化SystemService的时候被调用。
onStart()方法
Services 运行时候被调用,并且此时需要对外公布Binder接口
publishBinderService(String,IBinder)方法
有时候会同时对外公布本地服务publishLocalService共系统进程调用。
onBootPhase(int)方法
在启动阶段会被调用多次,一直到PHASE_BOOT_COMPLETED
下面displayManagerService的使用方法也是按照这个流程来的。

4.displayManagerService 的构造方法

displayManagerService 构造方法代码如下:

public displayManagerService(Context context) {        this(context,new Injector());    }    @VisibleForTesting    displayManagerService(Context context,Injector injector) {        super(context);        mInjector = injector;        mContext = context;        // mHandler 用来发送 display 消息        mHandler = new displayManagerHandler(displayThread.get().getLooper());        mUiHandler = UiThread.getHandler();        mdisplayAdapterListener = new displayAdapterListener();        mSingledisplayDemoMode = SystemPropertIEs.getBoolean("persist.demo.singledisplay",false);        mDefaultdisplayDefaultcolorMode = mContext.getResources().getInteger(            com.androID.internal.R.integer.config_defaultdisplayDefaultcolorMode);        PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);        mGlobaldisplayBrightness = pm.getDefaultScreenBrightnessSetting();    }
5.displayManagerService 的onStart 方法

onStart 主要加载持久化数据(主要是显示设备的宽高等),发送 MSG_REGISTER_DEFAulT_disPLAY_ADAPTERS消息,对外公布Binder、Local Service等。onStart() 方法如下:

@OverrIDe    public voID onStart() {        // We need to pre-load the persistent data store so it's ready before the default display        // adapter is up so that we have it's configuration. We Could load it lazily,but since        // we're going to have to read it in eventually we may as well do it here rather than after        // we've waited for the display to register itself with us.        synchronized(mSyncRoot) {                        //1. 加载本地持久化数据            mPersistentDataStore.loadIfNeeded();            loadStabledisplayValuesLocked();        } // 2. 发送MSG_REGISTER_DEFAulT_disPLAY_ADAPTERS 消息       mHandler.sendEmptyMessage(MSG_REGISTER_DEFAulT_disPLAY_ADAPTERS);        //3.对外公布Binder、Local 服务        publishBinderService(Context.disPLAY_SERVICE,new BinderService(),true /*allowIsolated*/);        publishLocalService(displayManagerInternal.class,new LocalService());        publishLocalService(displaytransformManager.class,new displaytransformManager());    }
加载本地持久化数据
private 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 | XmlPullParserException ex) {            Slog.w(TAG,"Failed to load tv input manager persistent store data.",ex);            clearState();        } finally {            IoUtils.closeQuIEtly(is);        }    }

2.MSG_REGISTER_DEFAulT_disPLAY_ADAPTERS消息 处理方法如下:

private final class displayManagerHandler extends Handler {        public displayManagerHandler(Looper looper) {            super(looper,null,true /*async*/);        }        @OverrIDe        public voID handleMessage(Message msg) {            switch (msg.what) {                case MSG_REGISTER_DEFAulT_disPLAY_ADAPTERS:                    // a.注册默认的显示适配器                    registerDefaultdisplayAdapters();                    break;                case MSG_REGISTER_ADDITIONAL_disPLAY_ADAPTERS:                    registeradditionaldisplayAdapters();                    break;         ...    }

a.registerDefaultdisplayAdapters 实现方法如下:
registerDefaultdisplayAdapters 最主要功能就是将显示设备添加注册到mdisplayAdapters适配器中。

private voID registerDefaultdisplayAdapters() {        // Register default display adapters.        synchronized (mSyncRoot) {            // b. 主要的显示适配器,注册本地适配器lock            registerdisplayAdapterLocked(new LocaldisplayAdapter(                    mSyncRoot,mContext,mHandler,mdisplayAdapterListener));            ...        }

b. 主要的显示适配器,注册本地适配器lock registerdisplayAdapterLocked

private voID registerdisplayAdapterLocked(displayAdapter adapter) {        mdisplayAdapters.add(adapter);        adapter.registerLocked();    }

LocaldisplayAdapter 继承 displayAdapter ,主要为本地显示设备提供的适配器。

final class LocaldisplayAdapter extends displayAdapter {   ...    // Called with SyncRoot lock held.    public LocaldisplayAdapter(displayManagerService.SyncRoot syncRoot,Context context,Handler handler,Listener Listener) {        super(syncRoot,context,handler,Listener,TAG);    }    // registerdisplayAdapterLocked 中 调用 adapter.registerLocked();   @OverrIDe    public voID registerLocked() {        super.registerLocked();       // 1.创建显示设备热插拔时间的监听器        mHotplugReceiver = new HotplugdisplayEventReceiver(getHandler().getLooper());        for (int builtIndisplayID : BUILT_IN_disPLAY_IDS_TO_SCAN) {            //2.连接显示设备            tryConnectdisplayLocked(builtIndisplayID);        }    }       ...}

1.创建显示设备热插拔时间的监听器,部分代码如下:

private final class HotplugdisplayEventReceiver extends displayEventReceiver {        public HotplugdisplayEventReceiver(Looper looper) {            super(looper,VSYNC_SOURCE_APP);        }        @OverrIDe        public voID onHotplug(long timestampNanos,int builtIndisplayID,boolean connected) {            synchronized (getSyncRoot()) {                if (connected) {                   //连接显示设备                    tryConnectdisplayLocked(builtIndisplayID);                } else {                    trydisconnectdisplayLocked(builtIndisplayID);                }            }        }    }

2.连接显示设备,部分代码如下:

private voID tryConnectdisplayLocked(int builtIndisplayID) {        IBinder displayToken = SurfaceControl.getBuiltIndisplay(builtIndisplayID);        if (displayToken != null) {            SurfaceControl.PhysicaldisplayInfo[] configs =                    SurfaceControl.getdisplayConfigs(displayToken);                       int activeConfig = SurfaceControl.getActiveConfig(displayToken);                        int activecolorMode = SurfaceControl.getActivecolorMode(displayToken);            int[] colorModes = SurfaceControl.getdisplaycolorModes(displayToken);            LocaldisplayDevice device = mDevices.get(builtIndisplayID);            if (device == null) {                // display was added.                device = new LocaldisplayDevice(displayToken,builtIndisplayID,configs,activeConfig,colorModes,activecolorMode);                mDevices.put(builtIndisplayID,device);                senddisplayDeviceEventLocked(device,disPLAY_DEVICE_EVENT_ADDED);            } else if (device.updatePhysicaldisplayInfolocked(configs,activecolorMode)) {                // display propertIEs changed.                senddisplayDeviceEventLocked(device,disPLAY_DEVICE_EVENT_CHANGED);            }        } else {            // The display is no longer available. Ignore the attempt to add it.            // If it was connected but has already been disconnected,we'll get a            // disconnect event that will remove it from mDevices.        }    }

然后对 其他services以及app 公开publishBinderService接口

/**     * Publish the service so it is accessible to other services and apps.     */    protected final voID publishBinderService(String name,IBinder service,boolean allowIsolated) {        ServiceManager.addService(name,service,allowIsolated);    }

然后对 系统进程 公开publishLocalService接口

/**     * Publish the service so it is only accessible to the system process.     */    protected final <T> voID publishLocalService(Class<T> type,T service) {        LocalServices.addService(type,service);    }
6.displayManagerService 的onBootPhase(int phase) 方法
@OverrIDe    public voID onBootPhase(int phase) {        if (phase == PHASE_WAIT_FOR_DEFAulT_disPLAY) {            synchronized (mSyncRoot) {                long timeout = SystemClock.uptimeMillis()                        + mInjector.                ();                while (mLogicaldisplays.get(display.DEFAulT_disPLAY) == null ||                        mVirtualdisplayAdapter == null) {                    long delay = timeout - SystemClock.uptimeMillis();                    if (delay <= 0) {                        throw new RuntimeException("Timeout waiting for default display "                                + "to be initialized. Defaultdisplay="                                + mLogicaldisplays.get(display.DEFAulT_disPLAY)                                + ",mVirtualdisplayAdapter=" + mVirtualdisplayAdapter);                    }                    if (DEBUG) {                        Slog.d(TAG,"waitForDefaultdisplay: waiting,timeout=" + delay);                    }                    try {                        mSyncRoot.wait(delay);                    } catch (InterruptedException ex) {                    }                }            }        }    }

至此,本篇已结束,如有不对的地方,欢迎您的建议与指正。同时期待您的关注,感谢您的阅读,谢谢!

总结

以上是内存溢出为你收集整理的DisplayManagerService(一)全部内容,希望文章能够帮你解决DisplayManagerService(一)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1123356.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-30
下一篇 2022-05-30

发表评论

登录后才能评论

评论列表(0条)

保存