Android Display管理服務(wù)DMS

一.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è)大概的了解:


image.png

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)邏輯

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容