xdpi / ydpi were reported as 0

Bug: 6975723
Change-Id: Ia7fa37ec11e2308804f5034959a37e508d292d31
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index cdc8a9f..4cae692 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -79,8 +79,6 @@
       mDisplay(EGL_NO_DISPLAY),
       mSurface(EGL_NO_SURFACE),
       mContext(EGL_NO_CONTEXT),
-      mDpiX(), mDpiY(),
-      mDensity(),
       mDisplayWidth(), mDisplayHeight(), mFormat(),
       mFlags(),
       mPageFlipCount(),
@@ -103,18 +101,6 @@
     return mFlinger != NULL;
 }
 
-float DisplayDevice::getDpiX() const {
-    return mDpiX;
-}
-
-float DisplayDevice::getDpiY() const {
-    return mDpiY;
-}
-
-float DisplayDevice::getDensity() const {
-    return mDensity;
-}
-
 int DisplayDevice::getWidth() const {
     return mDisplayWidth;
 }
@@ -137,38 +123,6 @@
 
     int format;
     window->query(window, NATIVE_WINDOW_FORMAT, &format);
-    mDpiX = window->xdpi;
-    mDpiY = window->ydpi;
-
-    // TODO: Not sure if display density should handled by SF any longer
-    class Density {
-        static int getDensityFromProperty(char const* propName) {
-            char property[PROPERTY_VALUE_MAX];
-            int density = 0;
-            if (property_get(propName, property, NULL) > 0) {
-                density = atoi(property);
-            }
-            return density;
-        }
-    public:
-        static int getEmuDensity() {
-            return getDensityFromProperty("qemu.sf.lcd_density"); }
-        static int getBuildDensity()  {
-            return getDensityFromProperty("ro.sf.lcd_density"); }
-    };
-    // The density of the device is provided by a build property
-    mDensity = Density::getBuildDensity() / 160.0f;
-    if (mDensity == 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");
-        mDensity = mDpiX / 160.0f;
-    }
-    if (Density::getEmuDensity()) {
-        // if "qemu.sf.lcd_density" is specified, it overrides everything
-        mDpiX = mDpiY = mDensity = Density::getEmuDensity();
-        mDensity /= 160.0f;
-    }
 
     /*
      * Create our display's surface
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 0229dad..e9ba5ff 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -77,9 +77,6 @@
     // be instantaneous, might involve copying the frame buffer around.
     void flip(const Region& dirty) const;
 
-    float       getDpiX() const;
-    float       getDpiY() const;
-    float       getDensity() const;
     int         getWidth() const;
     int         getHeight() const;
     PixelFormat getFormat() const;
@@ -144,9 +141,6 @@
     EGLDisplay      mDisplay;
     EGLSurface      mSurface;
     EGLContext      mContext;
-    float           mDpiX;
-    float           mDpiY;
-    float           mDensity;
     int             mDisplayWidth;
     int             mDisplayHeight;
     PixelFormat     mFormat;
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
index f329136..6d33592 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
@@ -175,19 +175,6 @@
     }
 }
 
-float FramebufferSurface::getRefreshRate() const {
-    /* FIXME: REFRESH_RATE is a temporary HACK until we are able to report the
-     * refresh rate properly from the HAL. The WindowManagerService now relies
-     * on this value.
-     */
-#ifndef REFRESH_RATE
-    return fbDev->fps;
-#else
-    return REFRESH_RATE;
-#warning "refresh rate set via makefile to REFRESH_RATE"
-#endif
-}
-
 status_t FramebufferSurface::setUpdateRectangle(const Rect& r)
 {
     return INVALID_OPERATION;
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
index 95feaa0..bfa500b 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
@@ -38,9 +38,6 @@
 
     static sp<FramebufferSurface> create();
 
-    // TODO: this should be coming from HWC
-    float getRefreshRate() const;
-
     bool isUpdateOnDemand() const { return false; }
     status_t setUpdateRectangle(const Rect& updateRect);
     status_t compositionComplete();
@@ -52,6 +49,13 @@
     // BufferQueue.  The new buffer is returned in the 'buffer' argument.
     status_t nextBuffer(sp<GraphicBuffer>* buffer);
 
+    // FIXME: currently there are information we can only get from the
+    // FB HAL, and FB HAL can only be instantiated once on some devices.
+    // Eventually this functionality will have to move in HWC or somewhere else.
+    const framebuffer_device_t* getFbHal() const {
+        return fbDev;
+    }
+
 private:
     FramebufferSurface();
     virtual ~FramebufferSurface(); // this class cannot be overloaded
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 49aba52..c9df7a4 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -179,7 +179,8 @@
 
 HWComposer::HWComposer(
         const sp<SurfaceFlinger>& flinger,
-        EventHandler& handler)
+        EventHandler& handler,
+        framebuffer_device_t const* fbDev)
     : mFlinger(flinger),
       mModule(0), mHwc(0), mCapacity(0),
       mNumOVLayers(0), mNumFBLayers(0),
@@ -238,19 +239,14 @@
         }
     }
 
-    if (mRefreshPeriod == 0) {
-        // for compatibility, we attempt to get the refresh rate from
-        // the FB HAL if we couldn't get it from the HWC HAL.
-        hw_module_t const* module;
-        if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) {
-            framebuffer_device_t* fbDev;
-            int err = framebuffer_open(module, &fbDev);
-            if (!err && fbDev) {
-                mRefreshPeriod = nsecs_t(1e9 / fbDev->fps);
-                framebuffer_close(fbDev);
-            }
+
+    if (fbDev) {
+        if (mRefreshPeriod == 0) {
+            mRefreshPeriod = nsecs_t(1e9 / fbDev->fps);
+            ALOGW("getting VSYNC period from fb HAL: %lld", mRefreshPeriod);
         }
-        ALOGW("getting VSYNC period from fb HAL: %lld", mRefreshPeriod);
+        mDpiX = fbDev->xdpi;
+        mDpiY = fbDev->ydpi;
     }
 
     if (mRefreshPeriod == 0) {
@@ -313,6 +309,14 @@
     return now - ((now - mLastHwVSync) %  mRefreshPeriod);
 }
 
+float HWComposer::getDpiX() const {
+    return mDpiX;
+}
+
+float HWComposer::getDpiY() const {
+    return mDpiY;
+}
+
 void HWComposer::eventControl(int event, int enabled) {
     status_t err = NO_ERROR;
     if (mHwc && mHwc->common.version >= HWC_DEVICE_API_VERSION_0_3) {
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 52171f3..ac2257e 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -36,6 +36,7 @@
 struct hwc_composer_device_1;
 struct hwc_display_contents_1;
 struct hwc_procs;
+struct framebuffer_device_t;
 
 namespace android {
 // ---------------------------------------------------------------------------
@@ -62,7 +63,11 @@
         MAX_DISPLAYS
     };
 
-    HWComposer(const sp<SurfaceFlinger>& flinger, EventHandler& handler);
+    HWComposer(
+            const sp<SurfaceFlinger>& flinger,
+            EventHandler& handler,
+            framebuffer_device_t const* fbDev);
+
     ~HWComposer();
 
     status_t initCheck() const;
@@ -194,6 +199,8 @@
 
     nsecs_t getRefreshPeriod() const;
     nsecs_t getRefreshTimestamp() const;
+    float getDpiX() const;
+    float getDpiY() const;
 
     // this class is only used to fake the VSync event on systems that don't
     // have it.
@@ -245,6 +252,8 @@
     cb_context*                     mCBContext;
     EventHandler&                   mEventHandler;
     nsecs_t                         mRefreshPeriod;
+    float                           mDpiX;
+    float                           mDpiY;
     size_t                          mVSyncCount;
     sp<VSyncThread>                 mVSyncThread;
     bool                            mDebugForceFakeVSync;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index f2b49e8..ca3c216 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -420,7 +420,9 @@
     mEventQueue.setEventThread(mEventThread);
 
     // initialize the H/W composer
-    mHwc = new HWComposer(this, *static_cast<HWComposer::EventHandler *>(this));
+    mHwc = new HWComposer(this,
+            *static_cast<HWComposer::EventHandler *>(this),
+            fbs->getFbHal());
 
     // initialize our drawing state
     mDrawingState = mCurrentState;
@@ -497,13 +499,48 @@
     if (uint32_t(dpy) >= 1) {
         return BAD_INDEX;
     }
+
+    const HWComposer& hwc(getHwComposer());
+    float xdpi = hwc.getDpiX();
+    float ydpi = hwc.getDpiY();
+
+    // TODO: Not sure if display density should handled by SF any longer
+    class Density {
+        static int getDensityFromProperty(char const* propName) {
+            char property[PROPERTY_VALUE_MAX];
+            int density = 0;
+            if (property_get(propName, property, NULL) > 0) {
+                density = atoi(property);
+            }
+            return density;
+        }
+    public:
+        static int getEmuDensity() {
+            return getDensityFromProperty("qemu.sf.lcd_density"); }
+        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;
+    }
+
     sp<const DisplayDevice> hw(getDefaultDisplayDevice());
     info->w = hw->getWidth();
     info->h = hw->getHeight();
-    info->xdpi = hw->getDpiX();
-    info->ydpi = hw->getDpiY();
-    info->fps = float(1e9 / getHwComposer().getRefreshPeriod());
-    info->density = hw->getDensity();
+    info->xdpi = xdpi;
+    info->ydpi = ydpi;
+    info->fps = float(1e9 / hwc.getRefreshPeriod());
+    info->density = density;
     info->orientation = hw->getOrientation();
     // TODO: this needs to go away (currently needed only by webkit)
     getPixelFormatInfo(hw->getFormat(), &info->pixelFormatInfo);
@@ -1940,15 +1977,13 @@
             "  transaction-flags         : %08x\n"
             "  refresh-rate              : %f fps\n"
             "  x-dpi                     : %f\n"
-            "  y-dpi                     : %f\n"
-            "  density                   : %f\n",
+            "  y-dpi                     : %f\n",
             mLastSwapBufferTime/1000.0,
             mLastTransactionTime/1000.0,
             mTransactionFlags,
             1e9 / hwc.getRefreshPeriod(),
-            hw->getDpiX(),
-            hw->getDpiY(),
-            hw->getDensity());
+            hwc.getDpiX(),
+            hwc.getDpiY());
     result.append(buffer);
 
     snprintf(buffer, SIZE, "  eglSwapBuffers time: %f us\n",