一.DisplayManagerService
1.概述
???????DisplayManagerService是負(fù)責(zé)Display管理的系統(tǒng)服務(wù)之一,還有一些其他功能,包括屏幕亮度調(diào)節(jié)也涉及到DMS,其繼承自SystemService,因此具有SystemService子類的共性:具有生命周期方法,由SystemServer啟動(dòng)、注冊到系統(tǒng)服務(wù)中,通過Binder和其他組件進(jìn)行交互等。
Display類型
???????1.LocalDisplay
???????2.OverlayDisplay
???????3.WifiDisplay
???????4.VirtualDisplay
DisplayAdapter類型
???????每個(gè)Display對應(yīng)一個(gè) DisplayAdapter:
???????1.LocalDisplayAdapter:本地已經(jīng)存在的物理顯示屏設(shè)備。
???????2.OverlayDisplayAdapter:模擬輔助顯示設(shè)備,以類似浮動(dòng)窗口的形式顯示在主屏上,可以當(dāng)?shù)诙€(gè)屏幕使用,默認(rèn)也是鏡像主屏。
???????3.WifiDisplayAdapter:WiFi Display
???????4.VirtualDisplayAdapter:顯示一個(gè)虛擬屏幕
2.關(guān)系圖
???????先將Display管理相關(guān)的類之間的關(guān)系圖列出來,有個(gè)大概的了解:

3.啟動(dòng)過程
???????和SystemService的其他子類一樣,DMS由SystemServer通過反射的方式啟動(dòng),看一下DMS的構(gòu)造方法:
2.1.構(gòu)造方法
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();
}
???????構(gòu)造方法內(nèi)部邏輯比較簡單,主要邏輯為:
???????1.創(chuàng)建了mHandler和mUiHandler用來自身和其他消息隊(duì)列處理;
???????2.創(chuàng)建了DisplayAdapterListener對象,接收設(shè)備事件變化;
???????3.獲取系統(tǒng)服務(wù)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:管理創(chuàng)建的所有DisplayDevice;
???????3.LogicalDisplay:管理創(chuàng)建的所有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());
}
???????在該方法中,發(fā)送了MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS消息注冊DisplayAdapter[下一章進(jìn)行分析],公共BinderSerive供其他進(jìn)程進(jìn)行調(diào)用,公開LocalService供本進(jìn)程進(jìn)行使用;
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內(nèi)部,接收到phase為PHASE_WAIT_FOR_DEFAULT_DISPLAY時(shí),判斷是否創(chuàng)建了Display.DEFAULT_DISPLAY對應(yīng)的LogicalDisplay,且是否創(chuàng)建了VirtualDisplayAdapter對象,如果不滿足一個(gè)條件時(shí),需要等待;
2.4.systemReady()
public void systemReady(boolean safeMode, boolean onlyCore) {
synchronized (mSyncRoot) {
mSafeMode = safeMode;
mOnlyCore = onlyCore;
}
mHandler.sendEmptyMessage(MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS);
}
???????當(dāng)systemReady時(shí),發(fā)送MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS來注冊其他的adapter;
二.創(chuàng)建DisplayDevice和LogicalDisplay
???????前面在onStart()中分析到,發(fā)送了MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS消息,跟隨調(diào)用關(guān)系,會(huì)調(diào)用到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);
}
}
}
???????在該方法內(nèi)部執(zhí)行registerDisplayAdapterLocked(),會(huì)先創(chuàng)建LocalDisplayAdapter實(shí)例作為參數(shù)傳入,接下來創(chuàng)建了VirtualDisplayAdapter實(shí)例,然后執(zhí)行registerDisplayAdapterLocked()進(jìn)行注冊,先看一下registerDisplayAdapterLocked()實(shí)現(xiàn):
private void registerDisplayAdapterLocked(DisplayAdapter adapter) {
mDisplayAdapters.add(adapter);
adapter.registerLocked();
}
???????先將adapter存入mDisplayAdapters進(jìn)行管理,然后執(zhí)行DisplayAdapter的registerLocked();
???????接下來看一下LocalDisplayAdapter類實(shí)現(xiàn):
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,在構(gòu)造方法內(nèi)部執(zhí)行調(diào)用父類的構(gòu)造方法,一起看一下:
public DisplayAdapter(DisplayManagerService.SyncRoot syncRoot,
Context context, Handler handler, Listener listener, String name) {
mSyncRoot = syncRoot;
mContext = context;
mHandler = handler;
mListener = listener;
mName = name;
}
???????進(jìn)行一些賦值操作,后續(xù)相關(guān)邏輯會(huì)在父類里面進(jìn)行調(diào)用處理;接下來看一下registerLocked()方法:
@Override
public void registerLocked() {
super.registerLocked();
mHotplugReceiver = new HotplugDisplayEventReceiver(getHandler().getLooper());
for (int builtInDisplayId : BUILT_IN_DISPLAY_IDS_TO_SCAN) {
tryConnectDisplayLocked(builtInDisplayId);
}
}
???????當(dāng)調(diào)用registerLocked()時(shí),會(huì)遍歷BUILT_IN_DISPLAY_IDS_TO_SCAN執(zhí)行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.根據(jù)builtInDisplayId通過SurfaceControl的getBuiltInDisplay()從SurfaceFlinger獲取到對應(yīng)的displayToken;
???????2.如果是合法的displayToken,則進(jìn)行一系列獲取設(shè)備信息操作,接下來創(chuàng)建對象時(shí)會(huì)用到;
???????3.從mDevices獲取對應(yīng)的LocalDisplayDevice,首次創(chuàng)建時(shí)不存在,會(huì)進(jìn)行創(chuàng)建,然后加入mDevices進(jìn)行管理;
???????4.執(zhí)行sendDisplayDeviceEventLocked()進(jìn)行通知設(shè)備創(chuàng)建;
???????先看一下LocalDisplayDevice類實(shí)現(xiàn):
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類的內(nèi)部類,繼承DisplayDevice,在構(gòu)造方法內(nèi)部,主要執(zhí)行邏輯如下:
???????1.調(diào)用父類的構(gòu)造方法,LocalDisplayDevice設(shè)備mUniqueId為:local:0、local:1等;
???????2.將上述獲取的信息進(jìn)行賦值,包括PhysicalDisplayInfo等;
???????3.獲取本地服務(wù)LightsManager,然后獲取LightService對象mBacklight,用來屏幕亮度調(diào)節(jié);相關(guān)流程可參考Android 電源管理相關(guān)邏輯之PMS;
3.通知
???????上面講到,在創(chuàng)建完DisplayDevice后,先加入mDevices進(jìn)行管理,然后執(zhí)行sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_ADDED)來進(jìn)行通知下一步操作:
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();
}
???????最終會(huì)執(zhí)行mListener的onDisplayDeviceEvent()方法,前面講到在DMS內(nèi)部創(chuàng)建LocalDisplayAdapter時(shí),會(huì)傳入DisplayAdapterLister實(shí)例,DisplayAdapterLister實(shí)現(xiàn)了DisplayAdapter內(nèi)部的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);
}
}
}
???????當(dāng)收到DISPLAY_DEVICE_EVENT_ADDED時(shí),執(zhí)行handleDisplayDeviceAdded(device),device是剛才新創(chuàng)建的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對應(yīng)的DisplayDeviceInfo信息;
???????2.將新創(chuàng)建的設(shè)備加入到mDisplayDevices進(jìn)行管理;
???????3.執(zhí)行addLogicalDisplayLocked()創(chuàng)建DisplayDevice對應(yīng)的LogicalDisplay;
???????4.執(zhí)行updateDisplayStateLocked創(chuàng)建Runnable,來執(zhí)行一下屏幕狀態(tài)操作,比如:屏幕亮度;
???????5.執(zhí)行scheduleTraversalLocked()來進(jìn)行刷新,主要用來更新LayerStack到SurfaceFlinger中;
???????看一下addLogicalDisplayLocked()來創(chuàng)建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;
}
???????在該方法內(nèi)部可以看到,主要邏輯為:
???????1.通過assignDisplayIdLocked()來分配displayId,默認(rèn)為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里面屏幕內(nèi)容顯示是一一對應(yīng)關(guān)系;
private int assignLayerStackLocked(int displayId) {
return displayId;
}
???????3.將displayId,layerStack,device作為參數(shù)來創(chuàng)建LogicalDisplay對象,創(chuàng)建的LocalDisplayDevice對象賦值為LogicalDisplay的mPrimaryDisplayDevice變量;
public LogicalDisplay(int displayId, int layerStack, DisplayDevice primaryDisplayDevice) {
mDisplayId = displayId;
mLayerStack = layerStack;
mPrimaryDisplayDevice = primaryDisplayDevice;
}
???????4.調(diào)用display.updateLocked(mDisplayDevices)來將DisplayDevice對應(yīng)的設(shè)備信息DisplayDeviceInfo封裝為LogicalDisplay對應(yīng)的設(shè)備信息DisplayInfo;
???????5.將創(chuàng)建的LogicalDisplay存入mLogicalDisplays進(jìn)行管理;
???????6.執(zhí)行mSyncRoot.notifyAll()進(jìn)行喚醒操作;
???????7.執(zhí)行sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_ADDED)來發(fā)送設(shè)備添加通知;
5.總結(jié)
???????1.在DMS的onStart()方法內(nèi)部發(fā)送消息來創(chuàng)建LocalDisplayAdapter,然后執(zhí)行registerDisplayAdapterLocked(),繼而執(zhí)行LocalDisplayAdapter的registerLocked()方法;
???????2.在LocakDisplayAdapter()內(nèi)部執(zhí)行tryConnectDisplayLocked()來創(chuàng)建BUILT_IN_DISPLAY_IDS_TO_SCAN對應(yīng)的LocalDisplayDevice,最后發(fā)送DISPLAY_DEVICE_EVENT_ADDED事件通知;
???????3.DMS內(nèi)部收到回調(diào)通知,執(zhí)行handleDisplayDeviceAdded()來根據(jù)DisplayDevice創(chuàng)建對應(yīng)的LogicalDisplay;
三.創(chuàng)建Display、ActivityDisplay和DisplayContent
???????前面講到,在創(chuàng)建完LogicalDisplay時(shí),會(huì)執(zhí)行sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_ADDED)來發(fā)送設(shè)備添加通知來執(zhí)行后續(xù)操作,跟隨調(diào)用關(guān)系,一起看一下:
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();
}
???????在該方法內(nèi)部,會(huì)遍歷mCallbacks來執(zhí)行notifyDisplayEventAsync(),mCallbacks是CallbackRecord數(shù)組,通過registerCallback()來進(jìn)行注冊添加;
2.notifyDisplayEventAsync()
public void notifyDisplayEventAsync(int displayId, int event) {
try {
mCallback.onDisplayEvent(displayId, event);
}
}
???????mCallback是IDisplayManagerCallback實(shí)現(xiàn),具體實(shí)現(xiàn)是在DisplayManagerGlobal內(nèi)部,調(diào)用其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);
}
}
}
???????在執(zhí)行handleDisplayEvent()時(shí),會(huì)遍歷mDisplayListeners來執(zhí)行sendDisplayEvent(),mDisplayListeners是在registerDisplayEvent()內(nèi)部進(jìn)行注冊的,在執(zhí)行sendDisplayEvent()時(shí),通過DisplayListenerDelegate執(zhí)行mListener.onDisplayAdded(msg.arg1),mListener對應(yīng)DisplayListener實(shí)例;
???????ActivityStackSupervisor實(shí)現(xiàn)了DisplayListener接口,在setWindowManager()內(nèi)部進(jìn)行注冊:
void setWindowManager(WindowManagerService wm) {
synchronized (mService) {
...............
DisplayManager =
(DisplayManager)mService.mContext.getSystemService(Context.DISPLAY_SERVICE);
mDisplayManager.registerDisplayListener(this, null);
................
}
}
4.onDisplayAdded()
???????前面講到,在進(jìn)行通知時(shí),在sendDisplayEvent()是會(huì)調(diào)用mListener的onDisplayAdded(),mListener是DisplayListener的實(shí)現(xiàn)類,即:ActivityStackSupervisor,看一下onDisplayAdded()的實(shí)現(xiàn):
@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消息最終會(huì)執(zhí)行到handleDisplayAdded():
private void handleDisplayAdded(int displayId) {
synchronized (mService) {
getActivityDisplayOrCreateLocked(displayId);
}
}
???????在該方法內(nèi)部會(huì)根據(jù)displayId執(zhí)行g(shù)etActivityDisplayOrCreateLocked():
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對應(yīng)的ActivityDIsplay,由于是初次創(chuàng)建,所以不會(huì)存在;
???????2.通過DisplayManager的getDisplay()來創(chuàng)建displayId對應(yīng)的Display;
???????3.創(chuàng)建displayId對應(yīng)的ActivityDisplay實(shí)例;
???????4.將新創(chuàng)建的activityDisplay加入mActivityDisplays進(jìn)行管理;
???????5.通知WindowManagerService執(zhí)行onDisplayAdded()進(jìn)行創(chuàng)建DisplayContent;
???????接下來看一下通過mDisplayManager.getDisplay(displayId)來創(chuàng)建對應(yīng)的Display;
5.1.getDisplay()
public Display getDisplay(int displayId) {
synchronized (mLock) {
return getOrCreateDisplayLocked(displayId, false /*assumeValid*/);
}
}
???????在getDisplay()內(nèi)部調(diào)用了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.調(diào)用DisplayManagerGlobal的getCompatibleDisplay()來創(chuàng)建Display;
???????2.將創(chuàng)建的Display加入到mDisplays進(jìn)行管理;
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對應(yīng)的DisplayInfo,然后創(chuàng)建Display實(shí)例;
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實(shí)現(xiàn)是在DisplayManagerService內(nèi),最終調(diào)用方法為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內(nèi)獲取LogicalDisplay,然后在從內(nèi)部獲取到DisplayInfo,Display的內(nèi)部跟LogicalDisplay是強(qiáng)相關(guān)的;
???????接著前面getActivityDisplayOrCreateLocked()分析,在創(chuàng)建完Display時(shí),會(huì)通知WMS執(zhí)行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,因?yàn)榍懊嬉呀?jīng)創(chuàng)建了,所以此處可以獲取到;
???????2.執(zhí)行createDisplayContentLocked()創(chuàng)建Display對應(yīng)的DisplayContent;
5.2.1.createDisplayContentLocked()
private void createDisplayContentLocked(final Display display) {
mRoot.getDisplayContentOrCreate(display.getDisplayId());
}
???????通過RootWindowContainer來進(jìn)行創(chuàng)建:
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()來創(chuàng)建display對應(yīng)的DisplayContent,然后將DispalyContent加入到RootWindowContainer內(nèi)進(jìn)行管理;
???????以上介紹了DMS的啟動(dòng)流程、組成以及設(shè)備添加處理流程,可以發(fā)現(xiàn)Android系統(tǒng)幾大主要服務(wù)都是相輔相成的,系統(tǒng)的某一個(gè)服務(wù)單拎出來可能并不復(fù)雜,復(fù)雜的是和其他服務(wù)的關(guān)聯(lián),WMS監(jiān)聽到Display的接入會(huì)創(chuàng)建一個(gè)DisplayContent,用于由于管理該Display所有WindowState;AMS監(jiān)聽到Display接入會(huì)去創(chuàng)建ActivityDisplay,用于管理當(dāng)前屏幕的所有ActivityRecord等;
???????關(guān)于VirtualDisplay可以參考以下文章:Android VirtualDisplay相關(guān)邏輯