summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/ActivityThread.java10
-rw-r--r--core/java/android/hardware/display/DisplayManager.java9
-rw-r--r--services/java/com/android/server/SystemServer.java9
-rw-r--r--services/java/com/android/server/display/DisplayAdapter.java39
-rw-r--r--services/java/com/android/server/display/DisplayDevice.java14
-rw-r--r--services/java/com/android/server/display/DisplayDeviceInfo.java10
-rw-r--r--services/java/com/android/server/display/DisplayManagerService.java237
-rw-r--r--services/java/com/android/server/display/HeadlessDisplayAdapter.java38
-rw-r--r--services/java/com/android/server/display/SurfaceFlingerDisplayAdapter.java33
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);
+ }
}
}