一.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管理相关的类之间的关系图列出来,有个大概的了解:
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相关逻辑