Enable changing display configuration

This allows querying and switching display device configurations
through the ISurfaceComposer/SurfaceComposerClient interface.

Bug: 14320401
Change-Id: I8c22165698950e5da32204c1c4da92122f91a715
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index a346520..46e192e 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -502,7 +502,12 @@
     return mGraphicBufferProducerList.indexOf(surfaceTextureBinder) >= 0;
 }
 
-status_t SurfaceFlinger::getDisplayInfo(const sp<IBinder>& display, DisplayInfo* info) {
+status_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display,
+        Vector<DisplayInfo>* configs) {
+    if (configs == NULL) {
+        return BAD_VALUE;
+    }
+
     int32_t type = NAME_NOT_FOUND;
     for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
         if (display == mBuiltinDisplays[i]) {
@@ -515,10 +520,6 @@
         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) {
@@ -536,41 +537,63 @@
             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;
+    configs->clear();
 
-        // 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;
+    const Vector<HWComposer::DisplayConfig>& hwConfigs =
+            getHwComposer().getConfigs(type);
+    for (size_t c = 0; c < hwConfigs.size(); ++c) {
+        const HWComposer::DisplayConfig& hwConfig = hwConfigs[c];
+        DisplayInfo info = DisplayInfo();
+
+        float xdpi = hwConfig.xdpi;
+        float ydpi = hwConfig.ydpi;
+
+        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 = hwConfig.width;
+        info.h = hwConfig.height;
+        info.xdpi = xdpi;
+        info.ydpi = ydpi;
+        info.fps = float(1e9 / hwConfig.refresh);
+
+        // All non-virtual displays are currently considered secure.
+        info.secure = true;
+
+        configs->push_back(info);
     }
 
-    info->w = hwc.getWidth(type);
-    info->h = hwc.getHeight(type);
-    info->xdpi = xdpi;
-    info->ydpi = ydpi;
-    info->fps = float(1e9 / hwc.getRefreshPeriod(type));
+    return NO_ERROR;
+}
 
-    // All non-virtual displays are currently considered secure.
-    info->secure = true;
+int SurfaceFlinger::getActiveConfig(const sp<IBinder>& display) {
+    return 0;
+}
 
+status_t SurfaceFlinger::setActiveConfig(const sp<IBinder>& display, int id) {
     return NO_ERROR;
 }