(OK) Android graphic (12)—display上层相关概念、关系 - mLogicalDisplays.get(Display.DEFAULT_DISPLAY)


http://blog.csdn.net/lewif/article/details/50827430


涉及的java类

DisplayManagerService

Manages attached displays.
The DisplayManagerService manages the global lifecycle of displays,
decides how to configure logical displays based on the physical display devices currently
attached, sends notifications to the system and to applications when the state
changes, and so on.
The display manager service relies on a collection of DisplayAdapter components,
for discovering and configuring physical display devices attached to the system.
There are separate display adapters for each manner that devices are attached:
one display adapter for built-in local displays, one for simulated non-functional
displays when the system is headless, one for simulated overlay displays used for
development, one for wifi displays, etc.
Display adapters are only weakly coupled to the display manager service.
Display adapters communicate changes in display device state to the display manager
service asynchronously via a DisplayAdapter.Listener registered
by the display manager service.  This separation of concerns is important for
two main reasons.  First, it neatly encapsulates the responsibilities of these
two classes: display adapters handle individual display devices whereas
the display manager service handles the global state.  Second, it eliminates
the potential for deadlocks resulting from asynchronous display device discovery.

DisplayAdapter

A display adapter makes zero or more display devices available to the system
and provides facilities for discovering when displays are connected or disconnected.
For now, all display adapters are registered in the system server but
in principle it could be done from other processes.

现在支持的4种Adapter,分别对应不同类型的display。

1.LocalDisplayAdapter
A display adapter for the local displays managed by Surface Flinger
2.WifiDisplayAdapter
Connects to Wifi displays that implement the Miracast protocol.
This class is responsible for connecting to Wifi displays and mediating
the interactions between Media Server, Surface Flinger and the Display Manager Service.
3.VirtualDisplayAdapter
4.OverlayDisplayAdapter

DisplayDevice

 Represents a physical display device such as the built-in display an external monitor, or a WiFi display.
WifiDisplayDevice
VirtualDisplayDevice
OverlayDisplayDevice
LocalDisplayDevice

DisplayManagerGlobal

Manager communication with the display manager service on behalf of an application process.

DisplayManager

Manages the properties of attached displays.

LogicalDisplay

Describes how a logical display is configured.
At this time, we only support logical displays that are coupled to a particular
primary display device from which the logical display derives its basic properties
such as its size, density and refresh rate.
A logical display may be mirrored onto multiple display devices in addition to its
primary display device.  Note that the contents of a logical display may not
always be visible, even on its primary display device, such as in the case where
the primary display device is currently mirroring content from a different
logical display.
Note: The display manager architecture does not actually require logical displays
to be associated with any individual display device.  Logical displays and
display devices are orthogonal concepts.  Some mapping will exist between
logical displays and display devices but it can be many-to-many and
and some might have no relation at all.

Display

Provides information about the size and density of a logical display.

DisplayContent

Utility class for keeping track of the WindowStates and other pertinent contents of a particular Display.

DisplayInfo

Describes the characteristics of a particular logical display.

类之间的关系

以添加系统built in display为例,下面是各个类之间的关系图,

这里写图片描述

其中,LocalDisplayDevice中的mPhys是向surface flinger获取的display的硬件相关属性,而mDisplayToken是surfacefinger中为display创建的new BBinder对应的代理对象。

默认屏幕的上层初始化分析

1.
systemserver.Java

    /*--------------systemserver.java---------------------------*/
    // 专门为window manager创建了一个handler thread
    // Create a handler thread just for the window manager to enjoy.
        HandlerThread wmHandlerThread = new HandlerThread("WindowManager");
        wmHandlerThread.start();
        //创建一个window manager的Handler(looper是wmHandlerThread线程的)
        Handler wmHandler = new Handler(wmHandlerThread.getLooper());
        wmHandler.post(new Runnable() {
            @Override
            public void run() {
                //Looper.myLooper().setMessageLogging(new LogPrinter(
                //        android.util.Log.DEBUG, TAG, android.util.Log.LOG_ID_SYSTEM));
                android.os.Process.setThreadPriority(
                        android.os.Process.THREAD_PRIORITY_DISPLAY);
                android.os.Process.setCanSelfBackground(false);

                // For debug builds, log event loop stalls to dropbox for analysis.
                if (StrictMode.conditionallyEnableDebugLogging()) {
                    Slog.i(TAG, "Enabled StrictMode logging for WM Looper");
                }
            }
        });

    /*--------------systemserver.java---------------------------*/
    // DisplayManagerService display = null;
    // 新建DisplayManagerService服务
        Slog.i(TAG, "Display Manager");
            display = new DisplayManagerService(context, wmHandler);
            ServiceManager.addService(Context.DISPLAY_SERVICE, display, true);
         //需要等待第一个display初始化完成后,才继续进行,否则一直循环
        if (!display.waitForDefaultDisplay()) {
                reportWtf("Timeout waiting for default display to be initialized.",
                        new Throwable());
            }

    /*--------------DisplayManagerService.java---------------------------*/
    // 在mSyncRoot wait,直到mLogicalDisplays.get(Display.DEFAULT_DISPLAY)不为null
    // 即有地方添加了默认display的LogicalDisplay
    /**
     * Pauses the boot process to wait for the first display to be initialized.
     */
    public boolean waitForDefaultDisplay() {
        synchronized (mSyncRoot) {
            long timeout = SystemClock.uptimeMillis() + WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT;
            while (mLogicalDisplays.get(Display.DEFAULT_DISPLAY) == null) {
                long delay = timeout - SystemClock.uptimeMillis();
                if (delay <= 0) {
                    return false;
                }
                if (DEBUG) {
                    Slog.d(TAG, "waitForDefaultDisplay: waiting, timeout=" + delay);
                }
                try {
                    mSyncRoot.wait(delay);
                } catch (InterruptedException ex) {
                }
            }
        }
        return true;
    }

   /*--------------DisplayManagerService.java---------------------------*/
   public DisplayManagerService(Context context, Handler mainHandler) {
        mContext = context;
        mHeadless = SystemProperties.get(SYSTEM_HEADLESS).equals("1");
    //新建个DisplayManagerHandler
        mHandler = new DisplayManagerHandler(mainHandler.getLooper());
        mUiHandler = UiThread.getHandler();
        //新建个DisplayAdapterListener
        mDisplayAdapterListener = new DisplayAdapterListener();
        //persist.demo.singledisplay是只创建默认display的logical display
        mSingleDisplayDemoMode = SystemProperties.getBoolean("persist.demo.singledisplay", false);

        mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER);
    }

DisplayManagerHandler的消息处理函数,

  /*--------------DisplayManagerService.java---------------------------*/
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_ADAPTER:
                    registerDefaultDisplayAdapter();
                    break;

                case MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS:
                    registerAdditionalDisplayAdapters();
                    break;

                case MSG_DELIVER_DISPLAY_EVENT:
                    deliverDisplayEvent(msg.arg1, msg.arg2);
                    break;

                case MSG_REQUEST_TRAVERSAL:
                    mWindowManagerFuncs.requestTraversal();
                    break;

                case MSG_UPDATE_VIEWPORT: {
                    synchronized (mSyncRoot) {
                        mTempDefaultViewport.copyFrom(mDefaultViewport);
                        mTempExternalTouchViewport.copyFrom(mExternalTouchViewport);
                    }
                    mInputManagerFuncs.setDisplayViewports(
                            mTempDefaultViewport, mTempExternalTouchViewport);
                    break;
                }
            }
        }
    }

DisplayAdapterListener类,

      /*--------------DisplayManagerService.java---------------------------*/
    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;

                case DisplayAdapter.DISPLAY_DEVICE_EVENT_CHANGED:
                    handleDisplayDeviceChanged(device);
                    break;

                case DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED:
                    handleDisplayDeviceRemoved(device);
                    break;
            }
        }

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

    mHeadless = SystemProperties.get(SYSTEM_HEADLESS).equals("1");
/* ro.config.headless
    系统中判断ro.config.headless的总共有几个地方
    a、SurfaceControl.java在构造函数中判断如果是headless设备则抛出异常,说明headless的设备不应该构造任何显示画面
    b、在SystemUI中判断headless为true的情况下不启动WallpaperManagerService和SystemUIService
    c、在PhoneWindowManager的systemReady中判断headless为true的情况下不起动KeyguardServiceDelegate,不显示启动提示消息,屏蔽滑盖(lid)状态,屏蔽一些按键
    d、DisplayManagerService在创建默认显示设备的时候(registerDefaultDisplayAdapter)判断headless为true的情况下创建的是HeadlessDisplayAdapter而非LocalDisplayAdapter,前者并没有通过SurfaceFlinger.getBuiltInDisplay获取一个对应的DisplayDevice,也就是说上层的默认显示设备是空
    e、ActivityManagerService在startHomeActivityLocked断headless为true的情况下不启动HomeActivity,不能启动Activity,不能重启挂掉的进程(即使是persistent),不能更新屏幕配置。
*/

mHandler的MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER处理函数为,

/*--------------DisplayManagerService.java---------------------------*/
    private void registerDefaultDisplayAdapter() {
        // Register default display adapter.
        synchronized (mSyncRoot) {
            if (mHeadless) {
                registerDisplayAdapterLocked(new HeadlessDisplayAdapter(
                        mSyncRoot, mContext, mHandler, mDisplayAdapterListener));
            } else {
                //走这个分支
                registerDisplayAdapterLocked(new LocalDisplayAdapter(
                        mSyncRoot, mContext, mHandler, mDisplayAdapterListener));
            }
        }
    }

LocalDisplayAdapter构造函数的mHandler和mDisplayAdapterListener分别为DisplayManagerHandler和DisplayAdapterListener。

    /*--------------LocalDisplayAdapter.java---------------------------*/
    /* 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);
    }
    /*--------------DisplayAdapter.java---------------------------*/
   // 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;
    }

/*--------------DisplayManagerService.java---------------------------*/
//    private final ArrayList<DisplayAdapter> mDisplayAdapters = new ArrayList<DisplayAdapter>();
        private void registerDisplayAdapterLocked(DisplayAdapter adapter) {
        mDisplayAdapters.add(adapter);
        adapter.registerLocked();
    }

LocalDisplayAdapter.registerLocked(),

/*--------------LocalDisplayAdapter.java---------------------------*/       
        private static final int[] BUILT_IN_DISPLAY_IDS_TO_SCAN = new int[] {
            SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN,
            SurfaceControl.BUILT_IN_DISPLAY_ID_HDMI,
    };

    // LocalDisplayAdapter.registerLocked
        public void registerLocked() {
        super.registerLocked();

        mHotplugReceiver = new HotplugDisplayEventReceiver(getHandler().getLooper());
    //对默认屏幕和HDMI调用tryConnectDisplayLocked
        for (int builtInDisplayId : BUILT_IN_DISPLAY_IDS_TO_SCAN) {
            tryConnectDisplayLocked(builtInDisplayId);
        }
    }

调用tryConnectDisplayLocked(),这里主要是和底层framework去交互,获取底层注册的displays的相关信息。

      /*--------------LocalDisplayAdapter.java---------------------------*/ 
      // LocalDisplayAdapter.mDevices 
      // private final SparseArray<LocalDisplayDevice> mDevices =new SparseArray<LocalDisplayDevice>();
      private void tryConnectDisplayLocked(int builtInDisplayId) {
      //获取surface flinger中的new BBinder对应的client IBinder
        IBinder displayToken = SurfaceControl.getBuiltInDisplay(builtInDisplayId);
        //获取display的硬件属性,新建LocalDisplayDevice
        if (displayToken != null && SurfaceControl.getDisplayInfo(displayToken, mTempPhys)) {
            LocalDisplayDevice device = mDevices.get(builtInDisplayId);
            if (device == null) {
                // Display was added.
                device = new LocalDisplayDevice(displayToken, builtInDisplayId, mTempPhys);
                mDevices.put(builtInDisplayId, device);
                //给DisplayManagerService的DisplayManagerHandler发消息
                sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_ADDED);
            } else if (device.updatePhysicalDisplayInfoLocked(mTempPhys)) {
                // 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.
        }
    }

    /*--------------SurfaceControl.java---------------------------*/
    //SurfaceControl.java,都是static,类函数
    //通过id获取display token
    public static IBinder getBuiltInDisplay(int builtInDisplayId) {
        return nativeGetBuiltInDisplay(builtInDisplayId);
    }
        //通过display token,获取display硬件属性
        public static boolean getDisplayInfo(IBinder displayToken, SurfaceControl.PhysicalDisplayInfo outInfo) {
        if (displayToken == null) {
            throw new IllegalArgumentException("displayToken must not be null");
        }
        if (outInfo == null) {
            throw new IllegalArgumentException("outInfo must not be null");
        }
        return nativeGetDisplayInfo(displayToken, outInfo);
    }

其中,nativeGetBuiltInDisplay最终会调用surfaceflinger中的getBuiltInDisplay,通过Binder传回代理对象。

/*--------------SurfaceFlinger.cpp---------------------------*/
sp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) {
    if (uint32_t(id) >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
        ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id);
        return NULL;
    }
    return mBuiltinDisplays[id];
}

nativeGetDisplayInfo—>SurfaceFlinger::getDisplayInfo,

/*--------------SurfaceFlinger.cpp---------------------------*/
status_t SurfaceFlinger::getDisplayInfo(const sp<IBinder>& display, DisplayInfo* info) {
    int32_t type = NAME_NOT_FOUND;
    for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
        if (display == mBuiltinDisplays[i]) {
            type = i;
            break;
        }
    }

    if (type < 0) {
        return type;
    }

    const HWComposer& hwc(getHwComposer());
    float xdpi = hwc.getDpiX(type);
    float ydpi = hwc.getDpiY(type);

    // TODO: Not sure if display density should handled by SF any longer
    class Density {
        static int getDensityFromProperty(char const* propName) {
            char property[PROPERTY_VALUE_MAX];
            int density = 0;
            if (property_get(propName, property, NULL) > 0) {
                density = atoi(property);
            }
            return density;
        }
    public:
        static int getEmuDensity() {
            return getDensityFromProperty("qemu.sf.lcd_density"); }
        static int getBuildDensity()  {
            return getDensityFromProperty("ro.sf.lcd_density"); }
    };

    if (type == DisplayDevice::DISPLAY_PRIMARY) {
        // The density of the device is provided by a build property
        float density = Density::getBuildDensity() / 160.0f;
        if (density == 0) {
            // the build doesn't provide a density -- this is wrong!
            // use xdpi instead
            ALOGE("ro.sf.lcd_density must be defined as a build property");
            density = xdpi / 160.0f;
        }
        if (Density::getEmuDensity()) {
            // if "qemu.sf.lcd_density" is specified, it overrides everything
            xdpi = ydpi = density = Density::getEmuDensity();
            density /= 160.0f;
        }
        info->density = density;

        // TODO: this needs to go away (currently needed only by webkit)
        sp<const DisplayDevice> hw(getDefaultDisplayDevice());
        info->orientation = hw->getOrientation();
    } else {
        // TODO: where should this value come from?
        static const int TV_DENSITY = 213;
        info->density = TV_DENSITY / 160.0f;
        info->orientation = 0;
    }

    info->w = hwc.getWidth(type);
    info->h = hwc.getHeight(type);
    info->xdpi = xdpi;
    info->ydpi = ydpi;
    info->fps = float(1e9 / hwc.getRefreshPeriod(type));

    // All non-virtual displays are currently considered secure.
    info->secure = true;

    return NO_ERROR;
}

创建完LocalDisplayDevice,给DisplayManagerService的DisplayManagerHandler发消息,

    /*--------------DisplayAdapter.java---------------------------*/
    /**
     * Sends a display device event to the display adapter listener asynchronously.
     */
    protected final void sendDisplayDeviceEventLocked(
            final DisplayDevice device, final int event) {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                mListener.onDisplayDeviceEvent(device, event);
            }
        });
    }

LocalDisplayAdapter构造函数的mHandler和mDisplayAdapterListener分别为DisplayManagerHandler和DisplayAdapterListener,进而会去调用,

    /*--------------DisplayManagerService.java---------------------------*/
        private void handleDisplayDeviceAdded(DisplayDevice device) {
        synchronized (mSyncRoot) {
            handleDisplayDeviceAddedLocked(device);
        }
    }

    /*--------------DisplayManagerService.java---------------------------*/
    //输入为LocalDisplayDevice
    //    private final ArrayList<DisplayDevice> mDisplayDevices = new ArrayList<DisplayDevice>();
    private void handleDisplayDeviceAddedLocked(DisplayDevice device) {
        if (mDisplayDevices.contains(device)) {
            Slog.w(TAG, "Attempted to add already added display device: "
                    + device.getDisplayDeviceInfoLocked());
            return;
        }

        Slog.i(TAG, "Display device added: " + device.getDisplayDeviceInfoLocked());
    // List of all currently connected display devices.
    //将LocalDisplayDevice添加到mDisplayDevices
        mDisplayDevices.add(device);
        //为一个物理display添加一个logical display
        addLogicalDisplayLocked(device);
        updateDisplayBlankingLocked(device);
        scheduleTraversalLocked(false);
    }

为物理屏幕创建一个logical display,

/*--------------DisplayManagerService.java---------------------------*/
// Adds a new logical display based on the given display device.
    // Sends notifications if needed.
    private void addLogicalDisplayLocked(DisplayDevice device) {
        DisplayDeviceInfo deviceInfo = device.getDisplayDeviceInfoLocked();
        boolean isDefault = (deviceInfo.flags
                & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0;
        //主屏,同时mLogicalDisplays包含了这个device
        if (isDefault && mLogicalDisplays.get(Display.DEFAULT_DISPLAY) != null) {
            Slog.w(TAG, "Ignoring attempt to add a second default display: " + deviceInfo);
            isDefault = false;
        }
        //不是主屏,但是mSingleDisplayDemoMode为真,即设置了单屏模式
        //这时候不会去为这个物理display创建新的logical display,如果
        //有hdmi,这时候会mirror主屏的内容
        //看来逻辑display就是和显示的内容有很大的关系
        if (!isDefault && mSingleDisplayDemoMode) {
            Slog.i(TAG, "Not creating a logical display for a secondary display "
                    + " because single display demo mode is enabled: " + deviceInfo);
            return;
        }

        final int displayId = assignDisplayIdLocked(isDefault);
        // layerStack 就是displayId id,主屏0,hdmi 1
        final int layerStack = assignLayerStackLocked(displayId);

        //新建LogicalDisplay
        LogicalDisplay display = new LogicalDisplay(displayId, layerStack, device);
        display.updateLocked(mDisplayDevices);
        if (!display.isValidLocked()) {
            // This should never happen currently.
            Slog.w(TAG, "Ignoring display device because the logical display "
                    + "created from it was not considered valid: " + deviceInfo);
            return;
        }

        mLogicalDisplays.put(displayId, display);

        //如果添加的是built-in display,需要mSyncRoot.notifyAll()
        //因为systemserver.java中调用了waitForDefaultDisplay,这时候systemserver可以继续运行了
        // Wake up waitForDefaultDisplay.
        if (isDefault) {
            mSyncRoot.notifyAll();
        }
    //给mHandler发消息去处理
        sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_ADDED);
    }

    /*--------------LogicalDisplay.java---------------------------*/
    public LogicalDisplay(int displayId, int layerStack, DisplayDevice primaryDisplayDevice) {
        mDisplayId = displayId;
        mLayerStack = layerStack;
        mPrimaryDisplayDevice = primaryDisplayDevice;
    }

进而去调用mHandler的deliverDisplayEvent,先不去管mCallbacks是在哪里注册的,进而会去调用mTempCallbacks.get(i).notifyDisplayEventAsync(displayId, event);

   /*--------------DisplayManagerService.java---------------------------*/
   private void deliverDisplayEvent(int displayId, int event) {
        if (DEBUG) {
            Slog.d(TAG, "Delivering display event: displayId="
                    + displayId + ", event=" + event);
        }

        // Grab the lock and copy the callbacks.
        final int count;
        synchronized (mSyncRoot) {
        //这里的mCallbacks是哪里注册的??
            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();
    }

2. mCallbacks的由来, 上面在添加了默认display的LogicalDisplay后,会去调用下面代码,使得systemserver.java从waitForDefaultDisplay()中返回。

    /*--------------systemserver.java---------------------------*/
        if (isDefault) {
            mSyncRoot.notifyAll();
        }

进而,systemserver.java的initAndLoop() 会去注册WindowManagerService,

    /*--------------systemserver.java---------------------------*/
            wm = WindowManagerService.main(context, power, display, inputManager,
                    wmHandler, factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL,
                    !firstBoot, onlyCore);

下面分析下,WindowManagerService的构造函数中做了什么和display相关的,

    /*--------------WindowManagerService.java---------------------------*/
/*
class WindowManagerService extends IWindowManager.Stub
        implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs,
                DisplayManagerService.WindowManagerFuncs, DisplayManager.DisplayListener
*/
    //WindowManagerService实现了DisplayManager.DisplayListener接口

    private WindowManagerService(Context context, PowerManagerService pm,
            DisplayManagerService displayManager, InputManagerService inputManager,
            boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore) {

    mDisplayManagerService = displayManager;
    //新建个DisplayManager
    mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
    //由于WindowManagerService实现了DisplayManager.DisplayListener接口,
    //将WindowManagerService注册到DisplayManager中
    mDisplayManager.registerDisplayListener(this, null);    

    }

    /*--------------DisplayManager.java---------------------------*/
        public DisplayManager(Context context) {
        mContext = context;
        mGlobal = DisplayManagerGlobal.getInstance();
    }

/*--------------DisplayManagerGlobal.java---------------------------*/

// class DisplayManagerService extends IDisplayManager.Stub 
   public static DisplayManagerGlobal getInstance() {
        synchronized (DisplayManagerGlobal.class) {
            if (sInstance == null) {
                IBinder b = ServiceManager.getService(Context.DISPLAY_SERVICE);
                if (b != null) {
                //输入参数是DisplayManagerService 的代理
                    sInstance = new DisplayManagerGlobal(IDisplayManager.Stub.asInterface(b));
                }
            }
            return sInstance;
        }
    }

public final class DisplayManagerGlobal {

    //mDm是DisplayManagerService 的代理,用来和DisplayManagerService打交道
    private final IDisplayManager mDm;

        private DisplayManagerGlobal(IDisplayManager dm) {
        mDm = dm;
    }

}

接着将WindowManagerService注册到DisplayManager中,

    /*--------------DisplayManager.java---------------------------*/
        //输入参数为WindowManagerService,null    
        public void registerDisplayListener(DisplayListener listener, Handler handler) {
        mGlobal.registerDisplayListener(listener, handler);
    }

    /*--------------DisplayManagerGlobal.java---------------------------*/
        // DisplayManagerGlobal 
        public void registerDisplayListener(DisplayListener listener, Handler handler) {
        if (listener == null) {
            throw new IllegalArgumentException("listener must not be null");
        }
   // private final ArrayList<DisplayListenerDelegate> mDisplayListeners =
    //        new ArrayList<DisplayListenerDelegate>();
        synchronized (mLock) {
            int index = findDisplayListenerLocked(listener);
            if (index < 0) {
             //新建一个display listener的代理者
                mDisplayListeners.add(new DisplayListenerDelegate(listener, handler));
             //将DisplayManagerGlobal 和DisplayManagerService 联系起来
            registerCallbackIfNeededLocked();
            }
        }
    }

 public DisplayListenerDelegate(DisplayListener listener, Handler handler) {
            super(handler != null ? handler.getLooper() : Looper.myLooper(), null, true /*async*/);
            mListener = listener;
        }

/*--------------DisplayManagerGlobal.java---------------------------*/
// 将    DisplayManagerGlobal 和DisplayManagerService 联系起来
        private void registerCallbackIfNeededLocked() {
        if (mCallback == null) {
            mCallback = new DisplayManagerCallback();
            try {
                //调用DisplayManagerService 的registerCallback将
                //DisplayManagerGlobal 中的DisplayManagerCallback注册到DisplayManagerService中
                mDm.registerCallback(mCallback);
            } catch (RemoteException ex) {
                Log.e(TAG, "Failed to register callback with display manager service.", ex);
                mCallback = null;
            }
        }
    }   
private final class DisplayManagerCallback extends IDisplayManagerCallback.Stub {
        @Override
        public void onDisplayEvent(int displayId, int event) {
            if (DEBUG) {
                Log.d(TAG, "onDisplayEvent: displayId=" + displayId + ", event=" + event);
            }
            handleDisplayEvent(displayId, event);
        }
    }

DisplayManagerService 中调用registerCallback,将DisplayManagerCallback保存到mCallbacks中,

    /*--------------DisplayManagerService.java---------------------------*/
  @Override // Binder call
    public void registerCallback(IDisplayManagerCallback callback) {
        if (callback == null) {
            throw new IllegalArgumentException("listener must not be null");
        }

        synchronized (mSyncRoot) {
            int callingPid = Binder.getCallingPid();
            if (mCallbacks.get(callingPid) != null) {
                throw new SecurityException("The calling process has already "
                        + "registered an IDisplayManagerCallback.");
            }

            CallbackRecord record = new CallbackRecord(callingPid, callback);
            try {
                IBinder binder = callback.asBinder();
                binder.linkToDeath(record, 0);
            } catch (RemoteException ex) {
                // give up
                throw new RuntimeException(ex);
            }
        //保存的是CallbackRecord 
            mCallbacks.put(callingPid, record);
        }
    }

    /*--------------DisplayManagerService.java---------------------------*/
    private final class CallbackRecord implements DeathRecipient {
        public final int mPid;
        private final IDisplayManagerCallback mCallback;

        public boolean mWifiDisplayScanRequested;

        public CallbackRecord(int pid, IDisplayManagerCallback callback) {
            mPid = pid;
            mCallback = callback;
        }

        @Override
        public void binderDied() {
            if (DEBUG) {
                Slog.d(TAG, "Display listener for pid " + mPid + " died.");
            }
            onCallbackDied(this);
        }

        public void notifyDisplayEventAsync(int displayId, int event) {
            try {
                mCallback.onDisplayEvent(displayId, event);
            } catch (RemoteException ex) {
                Slog.w(TAG, "Failed to notify process "
                        + mPid + " that displays changed, assuming it died.", ex);
                binderDied();
            }
        }
    }

3. 回到最开始的deliverDisplayEvent函数,会调用CallbackRecord的notifyDisplayEventAsync(displayId, event),进而mCallback.onDisplayEvent(displayId, event),进而调用DisplayManagerGlobal的handleDisplayEvent(displayId, event)

/*--------------DisplayManagerService.java---------------------------*/
 private void deliverDisplayEvent(int displayId, int event) {
        if (DEBUG) {
            Slog.d(TAG, "Delivering display event: displayId="
                    + displayId + ", event=" + event);
        }

        // Grab the lock and copy the callbacks.
        final int count;
        synchronized (mSyncRoot) {
        //这里的mCallbacks是哪里注册的??
            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();
    }

handleDisplayEvent中的mDisplayListeners就是前面注册的DisplayListenerDelegate,其中的listener和handler分别为WindowManagerService和null,


/*--------------DisplayManagerGlobal.java---------------------------*/
    private void handleDisplayEvent(int displayId, int event) {
        synchronized (mLock) {
            if (USE_CACHE) {
                mDisplayInfoCache.remove(displayId);

                if (event == EVENT_DISPLAY_ADDED || event == EVENT_DISPLAY_REMOVED) {
                    mDisplayIdCache = null;
                }
            }

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

调用DisplayListenerDelegate 的sendDisplayEvent,进而调用mListener.onDisplayAdded(msg.arg1);,即WindowManagerService的onDisplayAdded,


/*--------------DisplayManagerGlobal.java---------------------------*/
 private static final class DisplayListenerDelegate extends Handler {
        public final DisplayListener mListener;

        public DisplayListenerDelegate(DisplayListener listener, Handler handler) {
            super(handler != null ? handler.getLooper() : Looper.myLooper(), null, true /*async*/);
            mListener = listener;
        }

        public void sendDisplayEvent(int displayId, int event) {
            Message msg = obtainMessage(event, displayId, 0);
            sendMessage(msg);
        }

        public void clearEvents() {
            removeCallbacksAndMessages(null);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case EVENT_DISPLAY_ADDED:
                    mListener.onDisplayAdded(msg.arg1);
                    break;
                case EVENT_DISPLAY_CHANGED:
                    mListener.onDisplayChanged(msg.arg1);
                    break;
                case EVENT_DISPLAY_REMOVED:
                    mListener.onDisplayRemoved(msg.arg1);
                    break;
            }
        }
    }
}

转到WindowManagerService中,

    /*--------------WindowManagerService.java---------------------------*/
    @Override
    public void onDisplayAdded(int displayId) {
        mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_ADDED, displayId, 0));
    }

    /*--------------WindowManagerService.java---------------------------*/
                    case DO_DISPLAY_ADDED:
                    synchronized (mWindowMap) {
                        handleDisplayAddedLocked(msg.arg1);
                    }
                    break;

        private void handleDisplayAddedLocked(int displayId) {
        final Display display = mDisplayManager.getDisplay(displayId);
        if (display != null) {
            createDisplayContentLocked(display);
            displayReady(displayId);
        }
    }

调用DisplayManager的getDisplay,

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

    /*--------------DisplayManager.java---------------------------*/
    //  private final SparseArray<Display> mDisplays = new SparseArray<Display>();
        private Display getOrCreateDisplayLocked(int displayId, boolean assumeValid) {
        Display display = mDisplays.get(displayId);
        if (display == null) {
            display = mGlobal.getCompatibleDisplay(displayId,
                    mContext.getDisplayAdjustments(displayId));
            if (display != null) {
                mDisplays.put(displayId, display);
            }
        } else if (!assumeValid && !display.isValid()) {
            display = null;
        }
        return display;
    }

    /*--------------DisplayManagerGlobal.java---------------------------*/

    public Display getCompatibleDisplay(int displayId, DisplayAdjustments daj) {
        DisplayInfo displayInfo = getDisplayInfo(displayId);
        if (displayInfo == null) {
            return null;
        }
        return new Display(this, displayId, displayInfo, daj);
    }

/*--------------DisplayManagerGlobal.java---------------------------*/
//mDm DisplayManagerService
     public DisplayInfo getDisplayInfo(int displayId) {
        try {
            synchronized (mLock) {
                DisplayInfo info;
                if (USE_CACHE) {
                    info = mDisplayInfoCache.get(displayId);
                    if (info != null) {
                        return info;
                    }
                }
        //调用DisplayManagerService的getDisplayInfo,获取显示器信息
                info = mDm.getDisplayInfo(displayId);
                if (info == null) {
                    return null;
                }

                if (USE_CACHE) {
                    mDisplayInfoCache.put(displayId, info);
                }
                //前面已经注册过了,mCallback不为Null
                registerCallbackIfNeededLocked();

                if (DEBUG) {
                    Log.d(TAG, "getDisplayInfo: displayId=" + displayId + ", info=" + info);
                }
                return info;
            }
        } catch (RemoteException ex) {
            Log.e(TAG, "Could not get display information from display manager.", ex);
            return null;
        }
    }

    /*--------------DisplayManagerGlobal.java---------------------------*/
    //已经注册过了,mCallback不为Null
        private void registerCallbackIfNeededLocked() {
        if (mCallback == null) {
            mCallback = new DisplayManagerCallback();
            try {
                mDm.registerCallback(mCallback);
            } catch (RemoteException ex) {
                Log.e(TAG, "Failed to register callback with display manager service.", ex);
                mCallback = null;
            }
        }
    }

    /*--------------WindowManagerService.java---------------------------*/
    //Display已经创建,创建display content
    public void createDisplayContentLocked(final Display display) {
        if (display == null) {
            throw new IllegalArgumentException("getDisplayContent: display must not be null");
        }
        getDisplayContentLocked(display.getDisplayId());
    }

        /** All DisplayContents in the world, kept here */
    // SparseArray<DisplayContent> mDisplayContents = new SparseArray<DisplayContent>(2);

        public DisplayContent getDisplayContentLocked(final int displayId) {
        DisplayContent displayContent = mDisplayContents.get(displayId);
        if (displayContent == null) {
            final Display display = mDisplayManager.getDisplay(displayId);
            // 走到这个分支,创建displayContent 
            if (display != null) {
                displayContent = newDisplayContentLocked(display);
            }
        }
        return displayContent;
    }

新建一个DisplayContent,保存到WindowManagerService的mDisplayContents(displayId, displayContent)。

    private DisplayContent newDisplayContentLocked(final Display display) {
        DisplayContent displayContent = new DisplayContent(display, this);
        final int displayId = display.getDisplayId();
        mDisplayContents.put(displayId, displayContent);

        DisplayInfo displayInfo = displayContent.getDisplayInfo();
        final Rect rect = new Rect();
        mDisplaySettings.getOverscanLocked(displayInfo.name, rect);
        synchronized (displayContent.mDisplaySizeLock) {
            displayInfo.overscanLeft = rect.left;
            displayInfo.overscanTop = rect.top;
            displayInfo.overscanRight = rect.right;
            displayInfo.overscanBottom = rect.bottom;
            mDisplayManagerService.setDisplayInfoOverrideFromWindowManager(
                    displayId, displayInfo);
        }
        configureDisplayPolicyLocked(displayContent);

        // TODO: Create an input channel for each display with touch capability.
        if (displayId == Display.DEFAULT_DISPLAY) {
            displayContent.mTapDetector = new StackTapPointerEventListener(this, displayContent);
            registerPointerEventListener(displayContent.mTapDetector);
        }

        return displayContent;
    }


































































































































                                    
posted @ 2016-12-09 23:18  张同光  阅读(281)  评论(0编辑  收藏  举报