am 848c2dc9: Stub out display manager service implementation.

* commit '848c2dc93b6795e171f3dd6f64ea0be65e2762ca':
  Stub out display manager service implementation.
This commit is contained in:
Jeff Brown
2012-08-19 23:10:09 -07:00
committed by Android Git Automerger
9 changed files with 150 additions and 253 deletions

View File

@@ -1553,10 +1553,20 @@ public final class ActivityThread {
if (dm != null && !forceUpdate) { if (dm != null && !forceUpdate) {
return dm; 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) { if (dm == null) {
dm = new DisplayMetrics(); dm = new DisplayMetrics();
mDisplayMetrics.put(ci, dm); mDisplayMetrics.put(ci, dm);
} }
CompatibilityInfoHolder cih = new CompatibilityInfoHolder(); CompatibilityInfoHolder cih = new CompatibilityInfoHolder();
cih.set(ci); cih.set(ci);
Display d = WindowManagerImpl.getDefault().makeCompatible(cih).getDefaultDisplay(); Display d = WindowManagerImpl.getDefault().makeCompatible(cih).getDefaultDisplay();

View File

@@ -45,14 +45,19 @@ public final class DisplayManager {
/** /**
* Gets an instance of the display manager. * 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 * @hide
*/ */
public static DisplayManager getInstance() { public static DisplayManager getInstance() {
synchronized (DisplayManager.class) { synchronized (DisplayManager.class) {
if (sInstance == null) { if (sInstance == null) {
IBinder b = ServiceManager.getService(Context.DISPLAY_SERVICE); 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; return sInstance;
} }

View File

@@ -155,13 +155,12 @@ class ServerThread extends Thread {
power = new PowerManagerService(); power = new PowerManagerService();
ServiceManager.addService(Context.POWER_SERVICE, power); 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"); Slog.i(TAG, "Activity Manager");
context = ActivityManagerService.main(factoryTest); 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"); Slog.i(TAG, "Telephony Registry");
ServiceManager.addService("telephony.registry", new TelephonyRegistry(context)); ServiceManager.addService("telephony.registry", new TelephonyRegistry(context));

View File

@@ -16,38 +16,33 @@
package com.android.server.display; 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> * <p>
* For now, all display adapters are registered in the system server but * For now, all display adapters are registered in the system server but
* in principle it could be done from other processes. * in principle it could be done from other processes.
* </p> * </p>
*/ */
public abstract class DisplayAdapter { 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. * @return The display adapter name.
*/ */
public abstract String getName(); 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);
}
} }

View File

@@ -18,8 +18,20 @@ package com.android.server.display;
/** /**
* Represents a physical display device such as the built-in 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 { 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); public abstract void getInfo(DisplayDeviceInfo outInfo);
} }

View File

@@ -20,6 +20,12 @@ package com.android.server.display;
* Describes the characteristics of a physical display device. * Describes the characteristics of a physical display device.
*/ */
public final class DisplayDeviceInfo { 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. * The width of the display in its natural orientation, in pixels.
* This value is not affected by display rotation. * This value is not affected by display rotation.
@@ -38,6 +44,7 @@ public final class DisplayDeviceInfo {
public float yDpi; public float yDpi;
public void copyFrom(DisplayDeviceInfo other) { public void copyFrom(DisplayDeviceInfo other) {
name = other.name;
width = other.width; width = other.width;
height = other.height; height = other.height;
refreshRate = other.refreshRate; refreshRate = other.refreshRate;
@@ -46,9 +53,10 @@ public final class DisplayDeviceInfo {
yDpi = other.yDpi; yDpi = other.yDpi;
} }
// For debugging purposes
@Override @Override
public String toString() { public String toString() {
return width + " x " + height + ", " + refreshRate + " fps, " return "\"" + name + "\": " + width + " x " + height + ", " + refreshRate + " fps, "
+ "density " + densityDpi + ", " + xDpi + " x " + yDpi + " dpi"; + "density " + densityDpi + ", " + xDpi + " x " + yDpi + " dpi";
} }
} }

View File

@@ -22,8 +22,6 @@ import android.content.pm.PackageManager;
import android.hardware.display.IDisplayManager; import android.hardware.display.IDisplayManager;
import android.os.Binder; import android.os.Binder;
import android.os.SystemProperties; import android.os.SystemProperties;
import android.util.Slog;
import android.util.SparseArray;
import android.view.Display; import android.view.Display;
import android.view.DisplayInfo; import android.view.DisplayInfo;
import android.view.Surface; import android.view.Surface;
@@ -47,41 +45,27 @@ public final class DisplayManagerService extends IDisplayManager.Stub {
private final Object mLock = new Object(); private final Object mLock = new Object();
private Context mContext; private final Context mContext;
private final boolean mHeadless; private final boolean mHeadless;
private int mDisplayIdSeq = Display.DEFAULT_DISPLAY;
/** All registered DisplayAdapters. */
private final ArrayList<DisplayAdapter> mDisplayAdapters = new ArrayList<DisplayAdapter>(); private final ArrayList<DisplayAdapter> mDisplayAdapters = new ArrayList<DisplayAdapter>();
private final DisplayInfo mDefaultDisplayInfo = new DisplayInfo();
/** All the DisplayAdapters showing the given displayId. */ public DisplayManagerService(Context context) {
private final SparseArray<ArrayList<DisplayAdapter>> mLogicalToPhysicals = mContext = context;
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() {
mHeadless = SystemProperties.get(SYSTEM_HEADLESS).equals("1"); mHeadless = SystemProperties.get(SYSTEM_HEADLESS).equals("1");
registerDefaultDisplayAdapter(); registerDefaultDisplayAdapter();
} }
private void registerDefaultDisplayAdapter() { private void registerDefaultDisplayAdapter() {
if (mHeadless) { if (mHeadless) {
registerDisplayAdapter(new HeadlessDisplayAdapter()); registerDisplayAdapter(new HeadlessDisplayAdapter(mContext));
} else { } 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 // FIXME: this isn't the right API for the long term
public void getDefaultExternalDisplayDeviceInfo(DisplayDeviceInfo info) { public void getDefaultExternalDisplayDeviceInfo(DisplayDeviceInfo info) {
// hardcoded assuming 720p touch screen plugged into HDMI and USB // hardcoded assuming 720p touch screen plugged into HDMI and USB
@@ -90,6 +74,11 @@ public final class DisplayManagerService extends IDisplayManager.Stub {
info.height = 720; info.height = 720;
} }
/**
* Returns true if the device is headless.
*
* @return True if the device is headless.
*/
public boolean isHeadless() { public boolean isHeadless() {
return mHeadless; return mHeadless;
} }
@@ -101,12 +90,10 @@ public final class DisplayManagerService extends IDisplayManager.Stub {
*/ */
public void setDisplayInfo(int displayId, DisplayInfo info) { public void setDisplayInfo(int displayId, DisplayInfo info) {
synchronized (mLock) { synchronized (mLock) {
DisplayInfo localInfo = mDisplayInfos.get(displayId); if (displayId != Display.DEFAULT_DISPLAY) {
if (localInfo == null) { throw new UnsupportedOperationException();
localInfo = new DisplayInfo();
mDisplayInfos.put(displayId, localInfo);
} }
localInfo.copyFrom(info); mDefaultDisplayInfo.copyFrom(info);
} }
} }
@@ -118,177 +105,32 @@ public final class DisplayManagerService extends IDisplayManager.Stub {
@Override // Binder call @Override // Binder call
public boolean getDisplayInfo(int displayId, DisplayInfo outInfo) { public boolean getDisplayInfo(int displayId, DisplayInfo outInfo) {
synchronized (mLock) { synchronized (mLock) {
DisplayInfo localInfo = mDisplayInfos.get(displayId); if (displayId != Display.DEFAULT_DISPLAY) {
if (localInfo == null) {
return false; return false;
} }
outInfo.copyFrom(localInfo); outInfo.copyFrom(mDefaultDisplayInfo);
return true; return true;
} }
} }
/** private void registerDisplayAdapter(DisplayAdapter adapter) {
* Inform the service of a new physical display. A new logical displayId is created and the new mDisplayAdapters.add(adapter);
* physical display is immediately bound to it. Use removeAdapterFromDisplay to disconnect it. adapter.register(new DisplayAdapter.Listener() {
* @Override
* @param adapter The wrapper for information associated with the physical display. public void onDisplayDeviceAdded(DisplayDevice device) {
*/ DisplayDeviceInfo deviceInfo = new DisplayDeviceInfo();
public void registerDisplayAdapter(DisplayAdapter adapter) { device.getInfo(deviceInfo);
copyDisplayInfoFromDeviceInfo(mDefaultDisplayInfo, deviceInfo);
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); @Override
if (displayInfo == null) { public void onDisplayDeviceRemoved(DisplayDevice device) {
createDisplayInfoLocked(displayId, adapter);
} }
});
Integer oldDisplayId = adapter.getDisplayId();
if (oldDisplayId != Display.NO_DISPLAY) {
if (oldDisplayId == displayId) {
// adapter already added to displayId.
return;
}
removeAdapterLocked(adapter);
}
ArrayList<DisplayAdapter> list = mLogicalToPhysicals.get(displayId);
if (list == null) {
list = new ArrayList<DisplayAdapter>();
mLogicalToPhysicals.put(displayId, list);
}
list.add(adapter);
adapter.setDisplayId(displayId);
}
// TODO: Notify SurfaceFlinger of new addition.
} }
/** private void copyDisplayInfoFromDeviceInfo(
* Disconnect the physical display from whichever logical display it is attached to. DisplayInfo displayInfo, DisplayDeviceInfo deviceInfo) {
* @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) {
// Bootstrap the logical display using the physical display. // Bootstrap the logical display using the physical display.
displayInfo.appWidth = deviceInfo.width; displayInfo.appWidth = deviceInfo.width;
displayInfo.appHeight = deviceInfo.height; displayInfo.appHeight = deviceInfo.height;
@@ -319,19 +161,12 @@ public final class DisplayManagerService extends IDisplayManager.Stub {
pw.println("Headless: " + mHeadless); pw.println("Headless: " + mHeadless);
DisplayDeviceInfo info = new DisplayDeviceInfo(); synchronized (mLock) {
for (DisplayAdapter adapter : mDisplayAdapters) { for (DisplayAdapter adapter : mDisplayAdapters) {
pw.println("Display for adapter " + adapter.getName() pw.println("Adapter: " + adapter.getName());
+ " assigned to Display " + adapter.getDisplayId()); }
DisplayDevice device = adapter.getDisplayDevice();
pw.print(" "); pw.println("Default display: " + mDefaultDisplayInfo);
device.getInfo(info);
pw.println(info);
} }
} }
public interface DisplayCallback {
public void displayAdded(int displayId);
public void displayRemoved(int displayId);
}
} }

View File

@@ -16,23 +16,20 @@
package com.android.server.display; package com.android.server.display;
import android.content.Context;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
/** /**
* Provides a fake default display for headless systems. * Provides a fake default display for headless systems.
*/ */
public final class HeadlessDisplayAdapter extends DisplayAdapter { public final class HeadlessDisplayAdapter extends DisplayAdapter {
private final DisplayDevice mDefaultDisplay = new DisplayDevice() { private final Context mContext;
@Override private final HeadlessDisplayDevice mDefaultDisplayDevice;
public void getInfo(DisplayDeviceInfo outInfo) {
outInfo.width = 640; public HeadlessDisplayAdapter(Context context) {
outInfo.height = 480; mContext = context;
outInfo.refreshRate = 60; mDefaultDisplayDevice = new HeadlessDisplayDevice();
outInfo.densityDpi = DisplayMetrics.DENSITY_DEFAULT; }
outInfo.xDpi = 160;
outInfo.yDpi = 160;
}
};
@Override @Override
public String getName() { public String getName() {
@@ -40,7 +37,26 @@ public final class HeadlessDisplayAdapter extends DisplayAdapter {
} }
@Override @Override
public DisplayDevice getDisplayDevice() { public void register(Listener listener) {
return mDefaultDisplay; 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;
outInfo.densityDpi = DisplayMetrics.DENSITY_DEFAULT;
outInfo.xDpi = 160;
outInfo.yDpi = 160;
}
} }
} }

View File

@@ -16,18 +16,21 @@
package com.android.server.display; package com.android.server.display;
import android.content.Context;
/** /**
* A display adapter for the displays managed by Surface Flinger. * A display adapter for the displays managed by Surface Flinger.
*/ */
public final class SurfaceFlingerDisplayAdapter extends DisplayAdapter { public final class SurfaceFlingerDisplayAdapter extends DisplayAdapter {
private final Context mContext;
private final SurfaceFlingerDisplayDevice mDefaultDisplayDevice;
private static native void nativeGetDefaultDisplayDeviceInfo(DisplayDeviceInfo outInfo); private static native void nativeGetDefaultDisplayDeviceInfo(DisplayDeviceInfo outInfo);
private final DisplayDevice mDefaultDisplay = new DisplayDevice() { public SurfaceFlingerDisplayAdapter(Context context) {
@Override mContext = context;
public void getInfo(DisplayDeviceInfo outInfo) { mDefaultDisplayDevice = new SurfaceFlingerDisplayDevice();
nativeGetDefaultDisplayDeviceInfo(outInfo); }
}
};
@Override @Override
public String getName() { public String getName() {
@@ -35,7 +38,21 @@ public final class SurfaceFlingerDisplayAdapter extends DisplayAdapter {
} }
@Override @Override
public DisplayDevice getDisplayDevice() { public void register(Listener listener) {
return mDefaultDisplay; 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);
}
} }
} }