diff options
9 files changed, 148 insertions, 251 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 0438e77..2cdb086 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -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(); diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java index 640044b..dc79710 100644 --- a/core/java/android/hardware/display/DisplayManager.java +++ b/core/java/android/hardware/display/DisplayManager.java @@ -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; } diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index c471dd2..a117b06 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -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)); diff --git a/services/java/com/android/server/display/DisplayAdapter.java b/services/java/com/android/server/display/DisplayAdapter.java index b623906..f9fa7a8 100644 --- a/services/java/com/android/server/display/DisplayAdapter.java +++ b/services/java/com/android/server/display/DisplayAdapter.java @@ -16,38 +16,33 @@ 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); + } } diff --git a/services/java/com/android/server/display/DisplayDevice.java b/services/java/com/android/server/display/DisplayDevice.java index 6d723f2..57002ff 100644 --- a/services/java/com/android/server/display/DisplayDevice.java +++ b/services/java/com/android/server/display/DisplayDevice.java @@ -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); } diff --git a/services/java/com/android/server/display/DisplayDeviceInfo.java b/services/java/com/android/server/display/DisplayDeviceInfo.java index c60c2e9..9c0f964 100644 --- a/services/java/com/android/server/display/DisplayDeviceInfo.java +++ b/services/java/com/android/server/display/DisplayDeviceInfo.java @@ -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"; } } diff --git a/services/java/com/android/server/display/DisplayManagerService.java b/services/java/com/android/server/display/DisplayManagerService.java index 468bf21..7c0f8fd 100644 --- a/services/java/com/android/server/display/DisplayManagerService.java +++ b/services/java/com/android/server/display/DisplayManagerService.java @@ -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); + } } } diff --git a/services/java/com/android/server/display/HeadlessDisplayAdapter.java b/services/java/com/android/server/display/HeadlessDisplayAdapter.java index 3eaf40f..17c2360 100644 --- a/services/java/com/android/server/display/HeadlessDisplayAdapter.java +++ b/services/java/com/android/server/display/HeadlessDisplayAdapter.java @@ -16,15 +16,41 @@ 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; } } diff --git a/services/java/com/android/server/display/SurfaceFlingerDisplayAdapter.java b/services/java/com/android/server/display/SurfaceFlingerDisplayAdapter.java index 539f7c1..9531acb 100644 --- a/services/java/com/android/server/display/SurfaceFlingerDisplayAdapter.java +++ b/services/java/com/android/server/display/SurfaceFlingerDisplayAdapter.java @@ -16,18 +16,21 @@ 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); + } } } |
