one more step toward HDMI support

getDisplayInfo() now returns proper information for
HWC managed displays.

hotplug is sitll not supported; so this is not fully correct
as the information returned will be bogus if the HDMI screen
is not plugged in.

Bug: 7191563
Change-Id: If55d8e829fae0443571548155007f486cdf9bc9f
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 9429ae6..caec250 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -187,7 +187,10 @@
                     mDisplayData[HWC_DISPLAY_PRIMARY].refresh);
         }
     } else if (mHwc) {
-        queryDisplayProperties(HWC_DISPLAY_PRIMARY);
+        // here we're guaranteed to have at least HWC 1.1
+        for (size_t i =0 ; i<HWC_NUM_DISPLAY_TYPES ; i++) {
+            queryDisplayProperties(i);
+        }
     }
 
     if (needVSyncThread) {
@@ -319,7 +322,8 @@
 #define ANDROID_DENSITY_TV    213
 #define ANDROID_DENSITY_XHIGH 320
 
-void HWComposer::queryDisplayProperties(int disp) {
+status_t HWComposer::queryDisplayProperties(int disp) {
+
     LOG_ALWAYS_FATAL_IF(!mHwc || !hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1));
 
     // use zero as default value for unspecified attributes
@@ -329,13 +333,13 @@
     uint32_t config;
     size_t numConfigs = 1;
     status_t err = mHwc->getDisplayConfigs(mHwc, disp, &config, &numConfigs);
-    LOG_ALWAYS_FATAL_IF(err, "getDisplayAttributes failed (%s)", strerror(-err));
-
-    if (err == NO_ERROR) {
-        mHwc->getDisplayAttributes(mHwc, disp, config, DISPLAY_ATTRIBUTES,
-                values);
+    if (err != NO_ERROR) {
+        // this can happen if an unpluggable display is not connected
+        return err;
     }
 
+    mHwc->getDisplayAttributes(mHwc, disp, config, DISPLAY_ATTRIBUTES, values);
+
     int32_t w = 0, h = 0;
     for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) {
         switch (DISPLAY_ATTRIBUTES[i]) {
@@ -371,6 +375,7 @@
             mDisplayData[disp].ydpi = ANDROID_DENSITY_TV;
         }
     }
+    return NO_ERROR;
 }
 
 int32_t HWComposer::allocateDisplayId() {
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index f253ecc..4156332 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -274,7 +274,7 @@
     inline void vsync(int disp, int64_t timestamp);
     inline void hotplug(int disp, int connected);
 
-    void queryDisplayProperties(int disp);
+    status_t queryDisplayProperties(int disp);
 
     status_t setFramebufferTarget(int32_t id,
             const sp<Fence>& acquireFence, const sp<GraphicBuffer>& buf);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 38aa012..bd587f2 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -522,16 +522,21 @@
 }
 
 status_t SurfaceFlinger::getDisplayInfo(const sp<IBinder>& display, DisplayInfo* info) {
-    // TODO: this is mostly here only for compatibility
-    //       the display size is needed but the display metrics should come from elsewhere
-    if (display != mDefaultDisplays[ISurfaceComposer::eDisplayIdMain]) {
-        // TODO: additional displays not yet supported
-        return BAD_INDEX;
+    int32_t type = BAD_VALUE;
+    for (int i=0 ; i<DisplayDevice::NUM_DISPLAY_TYPES ; i++) {
+        if (display == mDefaultDisplays[i]) {
+            type = i;
+            break;
+        }
+    }
+
+    if (type < 0) {
+        return type;
     }
 
     const HWComposer& hwc(getHwComposer());
-    float xdpi = hwc.getDpiX(HWC_DISPLAY_PRIMARY);
-    float ydpi = hwc.getDpiY(HWC_DISPLAY_PRIMARY);
+    float xdpi = hwc.getDpiX(type);
+    float ydpi = hwc.getDpiY(type);
 
     // TODO: Not sure if display density should handled by SF any longer
     class Density {
@@ -549,30 +554,39 @@
         static int getBuildDensity()  {
             return getDensityFromProperty("ro.sf.lcd_density"); }
     };
-    // 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;
+
+    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();
+        getPixelFormatInfo(hw->getFormat(), &info->pixelFormatInfo);
+    } else {
+        // TODO: where should this value come from?
+        static const int TV_DENSITY = 213;
+        info->density = TV_DENSITY / 160.0f;
+        info->orientation = 0;
     }
 
-    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
-    info->w = hw->getWidth();
-    info->h = hw->getHeight();
+    info->w = hwc.getWidth(type);
+    info->h = hwc.getHeight(type);
     info->xdpi = xdpi;
     info->ydpi = ydpi;
-    info->fps = float(1e9 / hwc.getRefreshPeriod(HWC_DISPLAY_PRIMARY));
-    info->density = density;
-    info->orientation = hw->getOrientation();
-    // TODO: this needs to go away (currently needed only by webkit)
-    getPixelFormatInfo(hw->getFormat(), &info->pixelFormatInfo);
+    info->fps = float(1e9 / hwc.getRefreshPeriod(type));
     return NO_ERROR;
 }