OSDN Git Service

Stub out display manager service implementation.
authorJeff Brown <jeffbrown@google.com>
Mon, 20 Aug 2012 03:18:08 +0000 (20:18 -0700)
committerJeff Brown <jeffbrown@google.com>
Mon, 20 Aug 2012 04:21:37 +0000 (21:21 -0700)
Reverting to the previous stub as the display adapter registration
and the logical to physical mapping is not at all what we are going
to need moving forward.

Fixed up the service initialization order so that the display manager
service has a context from the start.

Change-Id: I717f2f1099c7a77180ef207c371ec8329258850a

core/java/android/app/ActivityThread.java
core/java/android/hardware/display/DisplayManager.java
services/java/com/android/server/SystemServer.java
services/java/com/android/server/display/DisplayAdapter.java
services/java/com/android/server/display/DisplayDevice.java
services/java/com/android/server/display/DisplayDeviceInfo.java
services/java/com/android/server/display/DisplayManagerService.java
services/java/com/android/server/display/HeadlessDisplayAdapter.java
services/java/com/android/server/display/SurfaceFlingerDisplayAdapter.java

index 0438e77..2cdb086 100644 (file)
@@ -1553,10 +1553,20 @@ public final class ActivityThread {
         if (dm != null && !forceUpdate) {
             return dm;
         }
+
+        DisplayManager displayManager = DisplayManager.getInstance();
+        if (displayManager == null) {
+            // may be null early in system startup
+            dm = new DisplayMetrics();
+            dm.setToDefaults();
+            return dm;
+        }
+
         if (dm == null) {
             dm = new DisplayMetrics();
             mDisplayMetrics.put(ci, dm);
         }
+
         CompatibilityInfoHolder cih = new CompatibilityInfoHolder();
         cih.set(ci);
         Display d = WindowManagerImpl.getDefault().makeCompatible(cih).getDefaultDisplay();
index 640044b..dc79710 100644 (file)
@@ -45,14 +45,19 @@ public final class DisplayManager {
 
     /**
      * Gets an instance of the display manager.
-     * @return The display manager instance.
+     *
+     * @return The display manager instance, may be null early in system startup
+     * before the display manager has been fully initialized.
+     *
      * @hide
      */
     public static DisplayManager getInstance() {
         synchronized (DisplayManager.class) {
             if (sInstance == null) {
                 IBinder b = ServiceManager.getService(Context.DISPLAY_SERVICE);
-                sInstance = new DisplayManager(IDisplayManager.Stub.asInterface(b));
+                if (b != null) {
+                    sInstance = new DisplayManager(IDisplayManager.Stub.asInterface(b));
+                }
             }
             return sInstance;
         }
index c471dd2..a117b06 100644 (file)
@@ -155,13 +155,12 @@ class ServerThread extends Thread {
             power = new PowerManagerService();
             ServiceManager.addService(Context.POWER_SERVICE, power);
 
-            Slog.i(TAG, "Display Manager");
-            display = new DisplayManagerService();
-            ServiceManager.addService(Context.DISPLAY_SERVICE, display, true);
-
             Slog.i(TAG, "Activity Manager");
             context = ActivityManagerService.main(factoryTest);
-            display.setContext(context);
+
+            Slog.i(TAG, "Display Manager");
+            display = new DisplayManagerService(context);
+            ServiceManager.addService(Context.DISPLAY_SERVICE, display, true);
 
             Slog.i(TAG, "Telephony Registry");
             ServiceManager.addService("telephony.registry", new TelephonyRegistry(context));
index b623906..f9fa7a8 100644 (file)
 
 package com.android.server.display;
 
-import android.view.Display;
-
 /**
- * A display adapter makes a single display devices available to the system.
+ * A display adapter makes zero or more display devices available to the system
+ * and provides facilities for discovering when displays are connected or disconnected.
  * <p>
  * For now, all display adapters are registered in the system server but
  * in principle it could be done from other processes.
  * </p>
  */
 public abstract class DisplayAdapter {
-    /** The current logical Display assignment for this adapter. Will change if other logical
-     * display is assigned to this adapter */
-    private int mDisplayId = Display.NO_DISPLAY;
-
-    /** Assign the displayId
-     * @hide */
-    public void setDisplayId(int displayId) {
-        mDisplayId = displayId;
-    }
-
-    /** Retrieve the displayId
-     * @hide */
-    public int getDisplayId() {
-        return mDisplayId;
-    }
-
     /**
-     * Gets the display adapter name.
+     * Gets the display adapter name for debugging purposes.
+     *
      * @return The display adapter name.
      */
     public abstract String getName();
 
-    // TODO: dynamically register display devices
-    public abstract DisplayDevice getDisplayDevice();
+    /**
+     * Registers the display adapter with the display manager.
+     * The display adapter should register any built-in display devices now.
+     * Other display devices can be registered dynamically later.
+     *
+     * @param listener The listener for callbacks.
+     */
+    public abstract void register(Listener listener);
+
+    public interface Listener {
+        public void onDisplayDeviceAdded(DisplayDevice device);
+        public void onDisplayDeviceRemoved(DisplayDevice device);
+    }
 }
index 6d723f2..57002ff 100644 (file)
@@ -18,8 +18,20 @@ package com.android.server.display;
 
 /**
  * Represents a physical display device such as the built-in display
- * or an external monitor.
+ * an external monitor, or a WiFi display.
  */
 public abstract class DisplayDevice {
+    /**
+     * Gets the display adapter that makes the display device available.
+     *
+     * @return The display adapter.
+     */
+    public abstract DisplayAdapter getAdapter();
+
+    /**
+     * Gets information about the display device.
+     *
+     * @param outInfo The object to populate with the information.
+     */
     public abstract void getInfo(DisplayDeviceInfo outInfo);
 }
index c60c2e9..9c0f964 100644 (file)
@@ -21,6 +21,12 @@ package com.android.server.display;
  */
 public final class DisplayDeviceInfo {
     /**
+     * Gets the name of the display device, which may be derived from
+     * EDID or other sources.  The name may be displayed to the user.
+     */
+    public String name;
+
+    /**
      * The width of the display in its natural orientation, in pixels.
      * This value is not affected by display rotation.
      */
@@ -38,6 +44,7 @@ public final class DisplayDeviceInfo {
     public float yDpi;
 
     public void copyFrom(DisplayDeviceInfo other) {
+        name = other.name;
         width = other.width;
         height = other.height;
         refreshRate = other.refreshRate;
@@ -46,9 +53,10 @@ public final class DisplayDeviceInfo {
         yDpi = other.yDpi;
     }
 
+    // For debugging purposes
     @Override
     public String toString() {
-        return width + " x " + height + ", " + refreshRate + " fps, "
+        return "\"" + name + "\": " + width + " x " + height + ", " + refreshRate + " fps, "
                 + "density " + densityDpi + ", " + xDpi + " x " + yDpi + " dpi";
     }
 }
index 468bf21..7c0f8fd 100644 (file)
@@ -22,8 +22,6 @@ import android.content.pm.PackageManager;
 import android.hardware.display.IDisplayManager;
 import android.os.Binder;
 import android.os.SystemProperties;
-import android.util.Slog;
-import android.util.SparseArray;
 import android.view.Display;
 import android.view.DisplayInfo;
 import android.view.Surface;
@@ -47,41 +45,27 @@ public final class DisplayManagerService extends IDisplayManager.Stub {
 
     private final Object mLock = new Object();
 
-    private Context mContext;
+    private final Context mContext;
     private final boolean mHeadless;
 
-    private int mDisplayIdSeq = Display.DEFAULT_DISPLAY;
-
-    /** All registered DisplayAdapters. */
     private final ArrayList<DisplayAdapter> mDisplayAdapters = new ArrayList<DisplayAdapter>();
+    private final DisplayInfo mDefaultDisplayInfo = new DisplayInfo();
 
-    /** All the DisplayAdapters showing the given displayId. */
-    private final SparseArray<ArrayList<DisplayAdapter>> mLogicalToPhysicals =
-            new SparseArray<ArrayList<DisplayAdapter>>();
-
-    /** All the DisplayInfos in the system indexed by deviceId */
-    private final SparseArray<DisplayInfo> mDisplayInfos = new SparseArray<DisplayInfo>();
-
-    private final ArrayList<DisplayCallback> mCallbacks =
-            new ArrayList<DisplayManagerService.DisplayCallback>();
-
-    public DisplayManagerService() {
+    public DisplayManagerService(Context context) {
+        mContext = context;
         mHeadless = SystemProperties.get(SYSTEM_HEADLESS).equals("1");
+
         registerDefaultDisplayAdapter();
     }
 
     private void registerDefaultDisplayAdapter() {
         if (mHeadless) {
-            registerDisplayAdapter(new HeadlessDisplayAdapter());
+            registerDisplayAdapter(new HeadlessDisplayAdapter(mContext));
         } else {
-            registerDisplayAdapter(new SurfaceFlingerDisplayAdapter());
+            registerDisplayAdapter(new SurfaceFlingerDisplayAdapter(mContext));
         }
     }
 
-    public void setContext(Context context) {
-        mContext = context;
-    }
-
     // FIXME: this isn't the right API for the long term
     public void getDefaultExternalDisplayDeviceInfo(DisplayDeviceInfo info) {
         // hardcoded assuming 720p touch screen plugged into HDMI and USB
@@ -90,6 +74,11 @@ public final class DisplayManagerService extends IDisplayManager.Stub {
         info.height = 720;
     }
 
+    /**
+     * Returns true if the device is headless.
+     *
+     * @return True if the device is headless.
+     */
     public boolean isHeadless() {
         return mHeadless;
     }
@@ -101,12 +90,10 @@ public final class DisplayManagerService extends IDisplayManager.Stub {
      */
     public void setDisplayInfo(int displayId, DisplayInfo info) {
         synchronized (mLock) {
-            DisplayInfo localInfo = mDisplayInfos.get(displayId);
-            if (localInfo == null) {
-                localInfo = new DisplayInfo();
-                mDisplayInfos.put(displayId, localInfo);
+            if (displayId != Display.DEFAULT_DISPLAY) {
+                throw new UnsupportedOperationException();
             }
-            localInfo.copyFrom(info);
+            mDefaultDisplayInfo.copyFrom(info);
         }
     }
 
@@ -118,177 +105,32 @@ public final class DisplayManagerService extends IDisplayManager.Stub {
     @Override // Binder call
     public boolean getDisplayInfo(int displayId, DisplayInfo outInfo) {
         synchronized (mLock) {
-            DisplayInfo localInfo = mDisplayInfos.get(displayId);
-            if (localInfo == null) {
+            if (displayId != Display.DEFAULT_DISPLAY) {
                 return false;
             }
-            outInfo.copyFrom(localInfo);
+            outInfo.copyFrom(mDefaultDisplayInfo);
             return true;
         }
     }
 
-    /**
-     * Inform the service of a new physical display. A new logical displayId is created and the new
-     * physical display is immediately bound to it. Use removeAdapterFromDisplay to disconnect it.
-     *
-     * @param adapter The wrapper for information associated with the physical display.
-     */
-    public void registerDisplayAdapter(DisplayAdapter adapter) {
-
-        int displayId;
-        DisplayCallback[] callbacks;
-
-        synchronized (mLock) {
-            displayId = mDisplayIdSeq;
-            do {
-                // Find the next unused displayId. (Pretend like it might ever wrap around).
-                mDisplayIdSeq++;
-                if (mDisplayIdSeq < 0) {
-                    mDisplayIdSeq = Display.DEFAULT_DISPLAY + 1;
-                }
-            } while (mDisplayInfos.get(mDisplayIdSeq) != null);
-
-            adapter.setDisplayId(displayId);
-
-            createDisplayInfoLocked(displayId, adapter);
-
-            ArrayList<DisplayAdapter> list = new ArrayList<DisplayAdapter>();
-            list.add(adapter);
-            mLogicalToPhysicals.put(displayId, list);
-
-            mDisplayAdapters.add(adapter);
-            callbacks = mCallbacks.toArray(new DisplayCallback[mCallbacks.size()]);
-        }
-
-        for (int i = callbacks.length - 1; i >= 0; i--) {
-            callbacks[i].displayAdded(displayId);
-        }
-
-        // TODO: Notify SurfaceFlinger of new addition.
-    }
-
-    /**
-     * Connect a logical display to a physical display. Will remove the physical display from any
-     * logical display it is currently attached to.
-     *
-     * @param displayId The logical display. Will be created if it does not already exist.
-     * @param adapter The physical display.
-     */
-    public void addAdapterToDisplay(int displayId, DisplayAdapter adapter) {
-        if (adapter == null) {
-            // TODO: Or throw NPE?
-            Slog.e(TAG, "addDeviceToDisplay: Attempt to add null adapter");
-            return;
-        }
-
-        synchronized (mLock) {
-            if (!mDisplayAdapters.contains(adapter)) {
-                // TOOD: Handle unregistered adapter with exception or return value.
-                Slog.e(TAG, "addDeviceToDisplay: Attempt to add an unregistered adapter");
-                return;
-            }
-
-            DisplayInfo displayInfo = mDisplayInfos.get(displayId);
-            if (displayInfo == null) {
-                createDisplayInfoLocked(displayId, adapter);
-            }
-
-            Integer oldDisplayId = adapter.getDisplayId();
-            if (oldDisplayId != Display.NO_DISPLAY) {
-                if (oldDisplayId == displayId) {
-                    // adapter already added to displayId.
-                    return;
-                }
-
-                removeAdapterLocked(adapter);
+    private void registerDisplayAdapter(DisplayAdapter adapter) {
+        mDisplayAdapters.add(adapter);
+        adapter.register(new DisplayAdapter.Listener() {
+            @Override
+            public void onDisplayDeviceAdded(DisplayDevice device) {
+                DisplayDeviceInfo deviceInfo = new DisplayDeviceInfo();
+                device.getInfo(deviceInfo);
+                copyDisplayInfoFromDeviceInfo(mDefaultDisplayInfo, deviceInfo);
             }
 
-            ArrayList<DisplayAdapter> list = mLogicalToPhysicals.get(displayId);
-            if (list == null) {
-                list = new ArrayList<DisplayAdapter>();
-                mLogicalToPhysicals.put(displayId, list);
+            @Override
+            public void onDisplayDeviceRemoved(DisplayDevice device) {
             }
-            list.add(adapter);
-            adapter.setDisplayId(displayId);
-        }
-
-        // TODO: Notify SurfaceFlinger of new addition.
-    }
-
-    /**
-     * Disconnect the physical display from whichever logical display it is attached to.
-     * @param adapter The physical display to detach.
-     */
-    public void removeAdapterFromDisplay(DisplayAdapter adapter) {
-        if (adapter == null) {
-            // TODO: Or throw NPE?
-            return;
-        }
-
-        synchronized (mLock) {
-            if (!mDisplayAdapters.contains(adapter)) {
-                // TOOD: Handle unregistered adapter with exception or return value.
-                Slog.e(TAG, "removeDeviceFromDisplay: Attempt to remove an unregistered adapter");
-                return;
-            }
-
-            removeAdapterLocked(adapter);
-        }
-
-        // TODO: Notify SurfaceFlinger of removal.
-    }
-
-    public void registerDisplayCallback(final DisplayCallback callback) {
-        synchronized (mLock) {
-            if (!mCallbacks.contains(callback)) {
-                mCallbacks.add(callback);
-            }
-        }
+        });
     }
 
-    public void unregisterDisplayCallback(final DisplayCallback callback) {
-        synchronized (mLock) {
-            mCallbacks.remove(callback);
-        }
-    }
-
-    /**
-     * Create a new logical DisplayInfo and fill it in with information from the physical display.
-     * @param displayId The logical identifier.
-     * @param adapter The physical display for initial values.
-     */
-    private void createDisplayInfoLocked(int displayId, DisplayAdapter adapter) {
-        DisplayInfo displayInfo = new DisplayInfo();
-        DisplayDeviceInfo deviceInfo = new DisplayDeviceInfo();
-        adapter.getDisplayDevice().getInfo(deviceInfo);
-        copyDisplayInfoFromDeviceInfo(displayInfo, deviceInfo);
-        mDisplayInfos.put(displayId, displayInfo);
-    }
-
-    /**
-     * Disconnect a physical display from its logical display. If there are no more physical
-     * displays attached to the logical display, delete the logical display.
-     * @param adapter The physical display to detach.
-     */
-    void removeAdapterLocked(DisplayAdapter adapter) {
-        int displayId = adapter.getDisplayId();
-        adapter.setDisplayId(Display.NO_DISPLAY);
-
-        ArrayList<DisplayAdapter> list = mLogicalToPhysicals.get(displayId);
-        if (list != null) {
-            list.remove(adapter);
-            if (list.isEmpty()) {
-                mLogicalToPhysicals.remove(displayId);
-                // TODO: Keep count of Windows attached to logical display and don't delete if
-                // there are any outstanding. Also, what keeps the WindowManager from continuing
-                // to use the logical display?
-                mDisplayInfos.remove(displayId);
-            }
-        }
-    }
-
-    private void copyDisplayInfoFromDeviceInfo(DisplayInfo displayInfo,
-                                               DisplayDeviceInfo deviceInfo) {
+    private void copyDisplayInfoFromDeviceInfo(
+            DisplayInfo displayInfo, DisplayDeviceInfo deviceInfo) {
         // Bootstrap the logical display using the physical display.
         displayInfo.appWidth = deviceInfo.width;
         displayInfo.appHeight = deviceInfo.height;
@@ -319,19 +161,12 @@ public final class DisplayManagerService extends IDisplayManager.Stub {
 
         pw.println("Headless: " + mHeadless);
 
-        DisplayDeviceInfo info = new DisplayDeviceInfo();
-        for (DisplayAdapter adapter : mDisplayAdapters) {
-            pw.println("Display for adapter " + adapter.getName()
-                + " assigned to Display " + adapter.getDisplayId());
-            DisplayDevice device = adapter.getDisplayDevice();
-            pw.print("  ");
-            device.getInfo(info);
-            pw.println(info);
-        }
-    }
+        synchronized (mLock) {
+            for (DisplayAdapter adapter : mDisplayAdapters) {
+                pw.println("Adapter: " + adapter.getName());
+            }
 
-    public interface DisplayCallback {
-        public void displayAdded(int displayId);
-        public void displayRemoved(int displayId);
+            pw.println("Default display: " + mDefaultDisplayInfo);
+        }
     }
 }
index 3eaf40f..17c2360 100644 (file)
 
 package com.android.server.display;
 
+import android.content.Context;
 import android.util.DisplayMetrics;
 
 /**
  * Provides a fake default display for headless systems.
  */
 public final class HeadlessDisplayAdapter extends DisplayAdapter {
-    private final DisplayDevice mDefaultDisplay = new DisplayDevice() {
+    private final Context mContext;
+    private final HeadlessDisplayDevice mDefaultDisplayDevice;
+
+    public HeadlessDisplayAdapter(Context context) {
+        mContext = context;
+        mDefaultDisplayDevice = new HeadlessDisplayDevice();
+    }
+
+    @Override
+    public String getName() {
+        return "HeadlessDisplayAdapter";
+    }
+
+    @Override
+    public void register(Listener listener) {
+        listener.onDisplayDeviceAdded(mDefaultDisplayDevice);
+    }
+
+    private final class HeadlessDisplayDevice extends DisplayDevice {
+        @Override
+        public DisplayAdapter getAdapter() {
+            return HeadlessDisplayAdapter.this;
+        }
+
         @Override
         public void getInfo(DisplayDeviceInfo outInfo) {
+            outInfo.name = mContext.getResources().getString(
+                    com.android.internal.R.string.display_manager_built_in_display);
             outInfo.width = 640;
             outInfo.height = 480;
             outInfo.refreshRate = 60;
@@ -32,15 +58,5 @@ public final class HeadlessDisplayAdapter extends DisplayAdapter {
             outInfo.xDpi = 160;
             outInfo.yDpi = 160;
         }
-    };
-
-    @Override
-    public String getName() {
-        return "HeadlessDisplayAdapter";
-    }
-
-    @Override
-    public DisplayDevice getDisplayDevice() {
-        return mDefaultDisplay;
     }
 }
index 539f7c1..9531acb 100644 (file)
 
 package com.android.server.display;
 
+import android.content.Context;
+
 /**
  * A display adapter for the displays managed by Surface Flinger.
  */
 public final class SurfaceFlingerDisplayAdapter extends DisplayAdapter {
+    private final Context mContext;
+    private final SurfaceFlingerDisplayDevice mDefaultDisplayDevice;
+
     private static native void nativeGetDefaultDisplayDeviceInfo(DisplayDeviceInfo outInfo);
 
-    private final DisplayDevice mDefaultDisplay = new DisplayDevice() {
-        @Override
-        public void getInfo(DisplayDeviceInfo outInfo) {
-            nativeGetDefaultDisplayDeviceInfo(outInfo);
-        }
-    };
+    public SurfaceFlingerDisplayAdapter(Context context) {
+        mContext = context;
+        mDefaultDisplayDevice = new SurfaceFlingerDisplayDevice();
+    }
 
     @Override
     public String getName() {
@@ -35,7 +38,21 @@ public final class SurfaceFlingerDisplayAdapter extends DisplayAdapter {
     }
 
     @Override
-    public DisplayDevice getDisplayDevice() {
-        return mDefaultDisplay;
+    public void register(Listener listener) {
+        listener.onDisplayDeviceAdded(mDefaultDisplayDevice);
+    }
+
+    private final class SurfaceFlingerDisplayDevice extends DisplayDevice {
+        @Override
+        public DisplayAdapter getAdapter() {
+            return SurfaceFlingerDisplayAdapter.this;
+        }
+
+        @Override
+        public void getInfo(DisplayDeviceInfo outInfo) {
+            outInfo.name = mContext.getResources().getString(
+                    com.android.internal.R.string.display_manager_built_in_display);
+            nativeGetDefaultDisplayDeviceInfo(outInfo);
+        }
     }
 }