Android Display管理服务DMS

一.DisplayManagerService

1.概述

       DisplayManagerService是负责Display管理的系统服务之一,还有一些其他功能,包括屏幕亮度调节也涉及到DMS,其继承自SystemService,因此具有SystemService子类的共性:具有生命周期方法,由SystemServer启动、注册到系统服务中,通过Binder和其他组件进行交互等。

Display类型

       1.LocalDisplay
       2.OverlayDisplay
       3.WifiDisplay
       4.VirtualDisplay

DisplayAdapter类型

       每个Display对应一个 DisplayAdapter:
       1.LocalDisplayAdapter:本地已经存在的物理显示屏设备。
       2.OverlayDisplayAdapter:模拟辅助显示设备,以类似浮动窗口的形式显示在主屏上,可以当第二个屏幕使用,默认也是镜像主屏。
       3.WifiDisplayAdapter:WiFi Display
       4.VirtualDisplayAdapter:显示一个虚拟屏幕

2.关系图

       先将Display管理相关的类之间的关系图列出来,有个大概的了解:


image.png

3.启动过程

       和SystemService的其他子类一样,DMS由SystemServer通过反射的方式启动,看一下DMS的构造方法:

2.1.构造方法

DisplayManagerService(Context context, Injector injector) {
    super(context);
    mInjector = injector;
    mContext = context;
    mHandler = new DisplayManagerHandler(DisplayThread.get().getLooper());
    mUiHandler = UiThread.getHandler();
    mDisplayAdapterListener = new DisplayAdapterListener();
    ...................
    PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
    mGlobalDisplayBrightness = pm.getMinimumScreenBrightnessSetting();
}

       构造方法内部逻辑比较简单,主要逻辑为:
       1.创建了mHandler和mUiHandler用来自身和其他消息队列处理;
       2.创建了DisplayAdapterListener对象,接收设备事件变化;
       3.获取系统服务PowerManger;

 // List of all currently registered display adapters.
 private final ArrayList<DisplayAdapter> mDisplayAdapters = new ArrayList<DisplayAdapter>();

// List of all currently connected display devices.
private final ArrayList<DisplayDevice> mDisplayDevices = new ArrayList<DisplayDevice>();

// List of all logical displays indexed by logical display id.
private final SparseArray<LogicalDisplay> mLogicalDisplays = new SparseArray<LogicalDisplay>();

       1.mDisplayAdapters:管理注册的所有DisplayAdapter;
       2.mDisplayDevices:管理创建的所有DisplayDevice;
       3.LogicalDisplay:管理创建的所有LogicalDisplay;

2.2.onStart()

@Override
public void onStart() {
    .....................
    mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS);
    publishBinderService(Context.DISPLAY_SERVICE, new BinderService(),
                true /*allowIsolated*/);
    publishLocalService(DisplayManagerInternal.class, new LocalService());
    publishLocalService(DisplayTransformManager.class, new DisplayTransformManager());
}

       在该方法中,发送了MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS消息注册DisplayAdapter[下一章进行分析],公共BinderSerive供其他进程进行调用,公开LocalService供本进程进行使用;

2.3.onBootPhase()

@Override
public void onBootPhase(int phase) {
    if (phase == PHASE_WAIT_FOR_DEFAULT_DISPLAY) {
        synchronized (mSyncRoot) {
            long timeout = SystemClock.uptimeMillis() + mInjector.getDefaultDisplayDelayTimeout();
            while (mLogicalDisplays.get(Display.DEFAULT_DISPLAY) == null || mVirtualDisplayAdapter == null) {
                long delay = timeout - SystemClock.uptimeMillis();
                try {
                    mSyncRoot.wait(delay);
                }
            }
    }
}

       在onBootPhase内部,接收到phase为PHASE_WAIT_FOR_DEFAULT_DISPLAY时,判断是否创建了Display.DEFAULT_DISPLAY对应的LogicalDisplay,且是否创建了VirtualDisplayAdapter对象,如果不满足一个条件时,需要等待;

2.4.systemReady()

public void systemReady(boolean safeMode, boolean onlyCore) {
    synchronized (mSyncRoot) {
        mSafeMode = safeMode;
        mOnlyCore = onlyCore;
    }

    mHandler.sendEmptyMessage(MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS);
}

       当systemReady时,发送MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS来注册其他的adapter;

二.创建DisplayDevice和LogicalDisplay

       前面在onStart()中分析到,发送了MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS消息,跟随调用关系,会调用到registerDefaultDisplayAdapters()方法,一起看一下:

private void registerDefaultDisplayAdapters() {
    // Register default display adapters.
    synchronized (mSyncRoot) {
        // main display adapter
        registerDisplayAdapterLocked(new LocalDisplayAdapter(
                    mSyncRoot, mContext, mHandler, mDisplayAdapterListener));

        mVirtualDisplayAdapter = mInjector.getVirtualDisplayAdapter(mSyncRoot, mContext,
                    mHandler, mDisplayAdapterListener);
        if (mVirtualDisplayAdapter != null) {
            registerDisplayAdapterLocked(mVirtualDisplayAdapter);
        }
    }
}

       在该方法内部执行registerDisplayAdapterLocked(),会先创建LocalDisplayAdapter实例作为参数传入,接下来创建了VirtualDisplayAdapter实例,然后执行registerDisplayAdapterLocked()进行注册,先看一下registerDisplayAdapterLocked()实现:

private void registerDisplayAdapterLocked(DisplayAdapter adapter) {
    mDisplayAdapters.add(adapter);
    adapter.registerLocked();
}

       先将adapter存入mDisplayAdapters进行管理,然后执行DisplayAdapter的registerLocked();
       接下来看一下LocalDisplayAdapter类实现:

1.LocalDisplayAdapter

final class LocalDisplayAdapter extends DisplayAdapter {
    .....................
    private static final String UNIQUE_ID_PREFIX = "local:";
    private static final int[] BUILT_IN_DISPLAY_IDS_TO_SCAN = new int[] {
            SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN,
            SurfaceControl.BUILT_IN_DISPLAY_ID_HDMI,
    };
    .....................
    public LocalDisplayAdapter(DisplayManagerService.SyncRoot syncRoot,
            Context context, Handler handler, Listener listener) {
        super(syncRoot, context, handler, listener, TAG);
    }
}

       LocalDisplayAdapter继承DisplayAdapter,在构造方法内部执行调用父类的构造方法,一起看一下:

public DisplayAdapter(DisplayManagerService.SyncRoot syncRoot,
            Context context, Handler handler, Listener listener, String name) {
    mSyncRoot = syncRoot;
    mContext = context;
    mHandler = handler;
    mListener = listener;
    mName = name;
}

       进行一些赋值操作,后续相关逻辑会在父类里面进行调用处理;接下来看一下registerLocked()方法:

@Override
public void registerLocked() {
    super.registerLocked();

    mHotplugReceiver = new HotplugDisplayEventReceiver(getHandler().getLooper());

    for (int builtInDisplayId : BUILT_IN_DISPLAY_IDS_TO_SCAN) {
        tryConnectDisplayLocked(builtInDisplayId);
    }
}

       当调用registerLocked()时,会遍历BUILT_IN_DISPLAY_IDS_TO_SCAN执行tryConnectDisplayLocked():

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, activeConfig,
                        colorModes, activeColorMode)) {
            // Display properties changed.
            sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_CHANGED);
        }
 }

       该方法主要做了以下几件事:
       1.根据builtInDisplayId通过SurfaceControl的getBuiltInDisplay()从SurfaceFlinger获取到对应的displayToken;
       2.如果是合法的displayToken,则进行一系列获取设备信息操作,接下来创建对象时会用到;
       3.从mDevices获取对应的LocalDisplayDevice,首次创建时不存在,会进行创建,然后加入mDevices进行管理;
       4.执行sendDisplayDeviceEventLocked()进行通知设备创建;
       先看一下LocalDisplayDevice类实现:

2.LocalDisplayDevice

private final class LocalDisplayDevice extends DisplayDevice {
    private final int mBuiltInDisplayId;
    private final Light mBacklight;
    ....................
    private DisplayDeviceInfo mInfo;
    ......................
    private  SurfaceControl.PhysicalDisplayInfo mDisplayInfos[];
    public LocalDisplayDevice(IBinder displayToken, int builtInDisplayId,
                SurfaceControl.PhysicalDisplayInfo[] physicalDisplayInfos, int activeDisplayInfo,
                int[] colorModes, int activeColorMode) {
        super(LocalDisplayAdapter.this, displayToken, UNIQUE_ID_PREFIX + builtInDisplayId,
                  builtInDisplayId);
        mBuiltInDisplayId = builtInDisplayId;
        updatePhysicalDisplayInfoLocked(physicalDisplayInfos, activeDisplayInfo,
                    colorModes, activeColorMode);
        updateColorModesLocked(colorModes, activeColorMode);
        if (mBuiltInDisplayId == SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN) {
            LightsManager lights = LocalServices.getService(LightsManager.class);
            mBacklight = lights.getLight(LightsManager.LIGHT_ID_BACKLIGHT);
        } else {
            mBacklight = null;
        }
        mHdrCapabilities = SurfaceControl.getHdrCapabilities(displayToken);
    }
    ..................
    ..................
}

       LocalDisplayDevice是LocalDisplayAdapter类的内部类,继承DisplayDevice,在构造方法内部,主要执行逻辑如下:
       1.调用父类的构造方法,LocalDisplayDevice设备mUniqueId为:local:0、local:1等;
       2.将上述获取的信息进行赋值,包括PhysicalDisplayInfo等;
       3.获取本地服务LightsManager,然后获取LightService对象mBacklight,用来屏幕亮度调节;相关流程可参考Android 电源管理相关逻辑之PMS

3.通知

       上面讲到,在创建完DisplayDevice后,先加入mDevices进行管理,然后执行sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_ADDED)来进行通知下一步操作:

protected final void sendDisplayDeviceEventLocked(final DisplayDevice device, final int event) {
    mHandler.post(new Runnable() {
        @Override
        public void run() {
            mListener.onDisplayDeviceEvent(device, event);
        }
    });
}

public interface Listener {
    public void onDisplayDeviceEvent(DisplayDevice device, int event);
    public void onTraversalRequested();
}

       最终会执行mListener的onDisplayDeviceEvent()方法,前面讲到在DMS内部创建LocalDisplayAdapter时,会传入DisplayAdapterLister实例,DisplayAdapterLister实现了DisplayAdapter内部的Listener接口:

private final class DisplayAdapterListener implements DisplayAdapter.Listener {
    @Override
    public void onDisplayDeviceEvent(DisplayDevice device, int event) {
        switch (event) {
           case DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED:
                handleDisplayDeviceAdded(device);
                break;
           ...........
        }
    }

    @Override
    public void onTraversalRequested() {
        synchronized (mSyncRoot) {
            scheduleTraversalLocked(false);
        }
    }
}

       当收到DISPLAY_DEVICE_EVENT_ADDED时,执行handleDisplayDeviceAdded(device),device是刚才新创建的LocalDisplayDevice;

private void handleDisplayDeviceAddedLocked(DisplayDevice device) {
    DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
    if (mDisplayDevices.contains(device)) {
        Slog.w(TAG, "Attempted to add already added display device: " + info);
        return;
    }

    Slog.i(TAG, "Display device added: " + info);
    device.mDebugLastLoggedDeviceInfo = info;

    mDisplayDevices.add(device);
    LogicalDisplay display = addLogicalDisplayLocked(device);
    Runnable work = updateDisplayStateLocked(device);
    if (work != null) {
        work.run();
    }
    scheduleTraversalLocked(false);
}

       1.先通过getDisplayDeviceInfoLocked()来获取到DisplayDevice对应的DisplayDeviceInfo信息;
       2.将新创建的设备加入到mDisplayDevices进行管理;
       3.执行addLogicalDisplayLocked()创建DisplayDevice对应的LogicalDisplay;
       4.执行updateDisplayStateLocked创建Runnable,来执行一下屏幕状态操作,比如:屏幕亮度;
       5.执行scheduleTraversalLocked()来进行刷新,主要用来更新LayerStack到SurfaceFlinger中;
       看一下addLogicalDisplayLocked()来创建LogicalDisplay:

4.LogicalDisplay

private LogicalDisplay addLogicalDisplayLocked(DisplayDevice device) {
    DisplayDeviceInfo deviceInfo = device.getDisplayDeviceInfoLocked();
    boolean isDefault = (deviceInfo.flags
                & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0;
    if (isDefault && mLogicalDisplays.get(Display.DEFAULT_DISPLAY) != null) {
        Slog.w(TAG, "Ignoring attempt to add a second default display: " + deviceInfo);
        isDefault = false;
    }
    ......................
    final int displayId = assignDisplayIdLocked(isDefault, device.getPhysicalId());
    final int layerStack = assignLayerStackLocked(displayId);

    LogicalDisplay display = new LogicalDisplay(displayId, layerStack, device);
    display.updateLocked(mDisplayDevices);
    ......................
    configureColorModeLocked(display, device);
    if (isDefault) {
        recordStableDisplayStatsIfNeededLocked(display);
    }
    mLogicalDisplays.put(displayId, display);

    // Wake up waitForDefaultDisplay.
    if (isDefault) {
        mSyncRoot.notifyAll();
    }

    sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_ADDED);
    return display;
}

       在该方法内部可以看到,主要逻辑为:
       1.通过assignDisplayIdLocked()来分配displayId,默认为0,1递增;

private int assignDisplayIdLocked(boolean isDefault, int physicalId) {
    if (physicalId >= SurfaceControl.BUILT_IN_DISPLAY_ID_EXT_MIN &&
        physicalId <= SurfaceControl.BUILT_IN_DISPLAY_ID_EXT_MAX) {
        return mNextBuiltInDisplayId++;
    }
    return assignDisplayIdLocked(isDefault);
}

       2.通过assignLayerStackLocked()为displayId分配layerStack,跟displayId保持一致,layerStack与SurfaceFlinger里面屏幕内容显示是一一对应关系;

private int assignLayerStackLocked(int displayId) {
    return displayId;
}

       3.将displayId,layerStack,device作为参数来创建LogicalDisplay对象,创建的LocalDisplayDevice对象赋值为LogicalDisplay的mPrimaryDisplayDevice变量;

public LogicalDisplay(int displayId, int layerStack, DisplayDevice primaryDisplayDevice) {
     mDisplayId = displayId;
     mLayerStack = layerStack;
     mPrimaryDisplayDevice = primaryDisplayDevice;
}

       4.调用display.updateLocked(mDisplayDevices)来将DisplayDevice对应的设备信息DisplayDeviceInfo封装为LogicalDisplay对应的设备信息DisplayInfo;
       5.将创建的LogicalDisplay存入mLogicalDisplays进行管理;
       6.执行mSyncRoot.notifyAll()进行唤醒操作;
       7.执行sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_ADDED)来发送设备添加通知;

5.总结

       1.在DMS的onStart()方法内部发送消息来创建LocalDisplayAdapter,然后执行registerDisplayAdapterLocked(),继而执行LocalDisplayAdapter的registerLocked()方法;
       2.在LocakDisplayAdapter()内部执行tryConnectDisplayLocked()来创建BUILT_IN_DISPLAY_IDS_TO_SCAN对应的LocalDisplayDevice,最后发送DISPLAY_DEVICE_EVENT_ADDED事件通知;
       3.DMS内部收到回调通知,执行handleDisplayDeviceAdded()来根据DisplayDevice创建对应的LogicalDisplay;

三.创建Display、ActivityDisplay和DisplayContent

       前面讲到,在创建完LogicalDisplay时,会执行sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_ADDED)来发送设备添加通知来执行后续操作,跟随调用关系,一起看一下:

1.deliverDisplayEvent()

public final SparseArray<CallbackRecord> mCallbacks = new SparseArray<CallbackRecord>();

private void deliverDisplayEvent(int displayId, int event) {
    ....................
    // Grab the lock and copy the callbacks.
    final int count;
    synchronized (mSyncRoot) {
        count = mCallbacks.size();
        mTempCallbacks.clear();
        for (int i = 0; i < count; i++) {
            mTempCallbacks.add(mCallbacks.valueAt(i));
        }
    }

    // After releasing the lock, send the notifications out.
    for (int i = 0; i < count; i++) {
        mTempCallbacks.get(i).notifyDisplayEventAsync(displayId, event);
    }
    mTempCallbacks.clear();
}

       在该方法内部,会遍历mCallbacks来执行notifyDisplayEventAsync(),mCallbacks是CallbackRecord数组,通过registerCallback()来进行注册添加;

2.notifyDisplayEventAsync()

public void notifyDisplayEventAsync(int displayId, int event) {
    try {
       mCallback.onDisplayEvent(displayId, event);
     }
}

       mCallback是IDisplayManagerCallback实现,具体实现是在DisplayManagerGlobal内部,调用其onDisplayEvent()方法:

3.onDisplayEvent()

private final class DisplayManagerCallback extends IDisplayManagerCallback.Stub {
    @Override
    public void onDisplayEvent(int displayId, int event) {
        handleDisplayEvent(displayId, event);
    }
}

private void handleDisplayEvent(int displayId, int event) {
    synchronized (mLock) {
        .......................
        final int numListeners = mDisplayListeners.size();
        for (int i = 0; i < numListeners; i++) {
            mDisplayListeners.get(i).sendDisplayEvent(displayId, event);
        }
    }
}

       在执行handleDisplayEvent()时,会遍历mDisplayListeners来执行sendDisplayEvent(),mDisplayListeners是在registerDisplayEvent()内部进行注册的,在执行sendDisplayEvent()时,通过DisplayListenerDelegate执行mListener.onDisplayAdded(msg.arg1),mListener对应DisplayListener实例;
       ActivityStackSupervisor实现了DisplayListener接口,在setWindowManager()内部进行注册:

void setWindowManager(WindowManagerService wm) {
    synchronized (mService) {
        ...............
        DisplayManager =
                    (DisplayManager)mService.mContext.getSystemService(Context.DISPLAY_SERVICE);
        mDisplayManager.registerDisplayListener(this, null);
        ................
    }
}

4.onDisplayAdded()

       前面讲到,在进行通知时,在sendDisplayEvent()是会调用mListener的onDisplayAdded(),mListener是DisplayListener的实现类,即:ActivityStackSupervisor,看一下onDisplayAdded()的实现:

@Override
public void onDisplayAdded(int displayId) {
    if (DEBUG_STACK) Slog.v(TAG, "Display added displayId=" + displayId);
    mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0));
}

       HANDLE_DISPLAY_ADDED消息最终会执行到handleDisplayAdded():

private void handleDisplayAdded(int displayId) {
    synchronized (mService) {
        getActivityDisplayOrCreateLocked(displayId);
    }
}

       在该方法内部会根据displayId执行getActivityDisplayOrCreateLocked():

5.getActivityDisplayOrCreateLocked()

private ActivityDisplay getActivityDisplayOrCreateLocked(int displayId) {
    ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
    if (activityDisplay != null) {
        return activityDisplay;
    }
    
    final Display display = mDisplayManager.getDisplay(displayId);

    activityDisplay = new ActivityDisplay(displayId);

    mActivityDisplays.put(displayId, activityDisplay);
    calculateDefaultMinimalSizeOfResizeableTasks(activityDisplay);
    mWindowManager.onDisplayAdded(displayId);
    return activityDisplay;
}

       1.从mActivityDisplays里面获取displayId对应的ActivityDIsplay,由于是初次创建,所以不会存在;
       2.通过DisplayManager的getDisplay()来创建displayId对应的Display;
       3.创建displayId对应的ActivityDisplay实例;
       4.将新创建的activityDisplay加入mActivityDisplays进行管理;
       5.通知WindowManagerService执行onDisplayAdded()进行创建DisplayContent;
       接下来看一下通过mDisplayManager.getDisplay(displayId)来创建对应的Display;

5.1.getDisplay()

public Display getDisplay(int displayId) {
    synchronized (mLock) {
        return getOrCreateDisplayLocked(displayId, false /*assumeValid*/);
    }
 }

       在getDisplay()内部调用了getOrCreateDisplayLocked():

private Display getOrCreateDisplayLocked(int displayId, boolean assumeValid) {
    Display display = mDisplays.get(displayId);
    if (display == null) {
        final Context context = mContext.getDisplay().getDisplayId() == displayId
                    ? mContext : mContext.getApplicationContext();

        display = mGlobal.getCompatibleDisplay(displayId, context.getResources());
        if (display != null) {
            mDisplays.put(displayId, display);
        }
    } else if (!assumeValid && !display.isValid()) {
        display = null;
    }
    return display;
}

       1.调用DisplayManagerGlobal的getCompatibleDisplay()来创建Display;
       2.将创建的Display加入到mDisplays进行管理;

5.1.1.getCompatibleDisplay()
public Display getCompatibleDisplay(int displayId, Resources resources) {
    DisplayInfo displayInfo = getDisplayInfo(displayId);
    if (displayInfo == null) {
        return null;
    }
    return new Display(this, displayId, displayInfo, resources);
}

       先通过getDisplayInfo()来获取displayId对应的DisplayInfo,然后创建Display实例;

5.1.2.getDisplayInfo()
public DisplayInfo getDisplayInfo(int displayId) {
    try {
        synchronized (mLock) {
            DisplayInfo info;
            .................
            info = mDm.getDisplayInfo(displayId);
            ...................
            return info;
        }
    } 
}

       通过IDisplayManager的getDisplayInfo()来获取DisplayInfo,IDisplayManager.Stub实现是在DisplayManagerService内,最终调用方法为getDisplayInfoInternal():

5.1.3.getDisplayInfoInternal()
private DisplayInfo getDisplayInfoInternal(int displayId, int callingUid) {
    synchronized (mSyncRoot) {
        LogicalDisplay display = mLogicalDisplays.get(displayId);
        if (display != null) {
            DisplayInfo info = display.getDisplayInfoLocked();
            if (info.hasAccess(callingUid)
                        || isUidPresentOnDisplayInternal(callingUid, displayId)) {
                return info;
            }
        }
        return null;
    }
}

       可以看到,是通过displayId从mLogicalDisplays内获取LogicalDisplay,然后在从内部获取到DisplayInfo,Display的内部跟LogicalDisplay是强相关的;
       接着前面getActivityDisplayOrCreateLocked()分析,在创建完Display时,会通知WMS执行onDisplayAdded():

5.2.onDisplayAdded()

public void onDisplayAdded(int displayId) {
     synchronized (mWindowMap) {
        final Display display = mDisplayManager.getDisplay(displayId);
        if (display != null) {
            createDisplayContentLocked(display);
            displayReady(displayId);
        }
        mWindowPlacerLocked.requestTraversal();
    }
}

       1.通过DisplayManager的getDisplay()获取Display,因为前面已经创建了,所以此处可以获取到;
       2.执行createDisplayContentLocked()创建Display对应的DisplayContent;

5.2.1.createDisplayContentLocked()
private void createDisplayContentLocked(final Display display) {
    mRoot.getDisplayContentOrCreate(display.getDisplayId());
}

       通过RootWindowContainer来进行创建:

5.2.2.getDisplayContentOrCreate()
DisplayContent getDisplayContentOrCreate(int displayId) {
    DisplayContent dc = getDisplayContent(displayId);

    if (dc == null) {
        final Display display = mService.mDisplayManager.getDisplay(displayId);
        if (display != null) {
            final long callingIdentity = Binder.clearCallingIdentity();
            try {
                dc = createDisplayContent(display);
            }
        }
    }
    return dc;
}

       通过createDisplayContent()来创建display对应的DisplayContent,然后将DispalyContent加入到RootWindowContainer内进行管理;
       以上介绍了DMS的启动流程、组成以及设备添加处理流程,可以发现Android系统几大主要服务都是相辅相成的,系统的某一个服务单拎出来可能并不复杂,复杂的是和其他服务的关联,WMS监听到Display的接入会创建一个DisplayContent,用于由于管理该Display所有WindowState;AMS监听到Display接入会去创建ActivityDisplay,用于管理当前屏幕的所有ActivityRecord等;
       关于VirtualDisplay可以参考以下文章:Android VirtualDisplay相关逻辑

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

推荐阅读更多精彩内容