hwc: Set display as active only after unblanking it

* For HDMI and non-Hybrid WFD solution, on receiving
online event, display hal sends hotplug connect to SF.
* In case of such displays, set them as active only
after receiving an unblank call.
* For Hybrid WFD solution, since display hal will not
be receiving unblank call from SF, set it as active
as part of processing online event itself.

Change-Id: I319f1576cba954da2024680568c37fedb1eb5d43
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index 113e916..0d6d17e 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -67,12 +67,12 @@
     }
 };
 
-/* In case of proprietary WFD session, we are fooling SF by piggybacking on
+/* In case of non-hybrid WFD session, we are fooling SF by piggybacking on
  * HDMI display ID for virtual. This helper is needed to differentiate their
  * paths in HAL.
  * TODO: Not needed once we have WFD client working on top of Google API's */
 
-static int getHWCDpy(hwc_context_t *ctx, int dpy) {
+static int getDpyforExternalDisplay(hwc_context_t *ctx, int dpy) {
     if(dpy == HWC_DISPLAY_EXTERNAL && ctx->mVirtualonExtActive)
         return HWC_DISPLAY_VIRTUAL;
     return dpy;
@@ -267,7 +267,7 @@
 
     for (int32_t i = numDisplays; i >= 0; i--) {
         hwc_display_contents_1_t *list = displays[i];
-        int dpy = getHWCDpy(ctx, i);
+        int dpy = getDpyforExternalDisplay(ctx, i);
         switch(dpy) {
             case HWC_DISPLAY_PRIMARY:
                 ret = hwc_prepare_primary(dev, list);
@@ -329,6 +329,14 @@
 
     Locker::Autolock _l(ctx->mDrawLock);
     int ret = 0, value = 0;
+
+    /* In case of non-hybrid WFD session, we are fooling SF by
+     * piggybacking on HDMI display ID for virtual.
+     * TODO: Not needed once we have WFD client working on top
+     * of Google API's.
+     */
+    dpy = getDpyforExternalDisplay(ctx,dpy);
+
     ALOGD_IF(BLANK_DEBUG, "%s: %s display: %d", __FUNCTION__,
           blank==1 ? "Blanking":"Unblanking", dpy);
     if(blank) {
@@ -355,13 +363,37 @@
             ctx->mExtDisplay->setHPD(1);
         }
 
-        /* Since SF is not aware of VIRTUAL DISPLAY being handle by HWC,
-         * it wont send blank / unblank events for it. We piggyback on
-         * PRIMARY DISPLAY events to release mdp pips and
-         * activate/deactive VIRTUAL DISPLAY */
+        ctx->dpyAttr[dpy].isActive = !blank;
+
+        if(ctx->mVirtualonExtActive) {
+            /* if mVirtualonExtActive is true, display hal will
+             * receive unblank calls for non-hybrid WFD solution
+             * since we piggyback on HDMI.
+             * TODO: Not needed once we have WFD client working on top
+             of Google API's */
+            break;
+        }
+    case HWC_DISPLAY_VIRTUAL:
+        /* There are two ways to reach this block of code.
+
+         * Display hal has received unblank call on HWC_DISPLAY_EXTERNAL
+         and ctx->mVirtualonExtActive is true. In this case, non-hybrid
+         WFD is active. If so, getDpyforExternalDisplay will return dpy
+         as HWC_DISPLAY_VIRTUAL.
+
+         * Display hal has received unblank call on HWC_DISPLAY_PRIMARY
+         and since SF is not aware of VIRTUAL DISPLAY being handle by HWC,
+         it wont send blank / unblank events for it. We piggyback on
+         PRIMARY DISPLAY events to release mdp pipes and
+         activate/deactivate VIRTUAL DISPLAY.
+
+         * TODO: This separate case statement is not needed once we have
+         WFD client working on top of Google API's.
+
+         */
 
         if(ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected) {
-            if(blank) {
+            if(blank and (!ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isPause)) {
                 int dpy = HWC_DISPLAY_VIRTUAL;
                 if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
                     ALOGE("%s: display commit fail for virtual!", __FUNCTION__);
@@ -378,13 +410,12 @@
                 ret = -1;
             }
         }
+        ctx->dpyAttr[dpy].isActive = !blank;
         break;
     default:
         return -EINVAL;
     }
 
-    ctx->dpyAttr[dpy].isActive = !blank;
-
     ALOGD_IF(BLANK_DEBUG, "%s: Done %s display: %d", __FUNCTION__,
           blank ? "blanking":"unblanking", dpy);
     return ret;
@@ -596,7 +627,7 @@
     hwc_context_t* ctx = (hwc_context_t*)(dev);
     for (uint32_t i = 0; i <= numDisplays; i++) {
         hwc_display_contents_1_t* list = displays[i];
-        int dpy = getHWCDpy(ctx, i);
+        int dpy = getDpyforExternalDisplay(ctx, i);
         switch(dpy) {
             case HWC_DISPLAY_PRIMARY:
                 ret = hwc_set_primary(ctx, list);
@@ -625,7 +656,7 @@
         uint32_t* configs, size_t* numConfigs) {
     int ret = 0;
     hwc_context_t* ctx = (hwc_context_t*)(dev);
-    disp = getHWCDpy(ctx, disp);
+    disp = getDpyforExternalDisplay(ctx, disp);
     //in 1.1 there is no way to choose a config, report as config id # 0
     //This config is passed to getDisplayAttributes. Ignore for now.
     switch(disp) {
@@ -655,7 +686,7 @@
         uint32_t config, const uint32_t* attributes, int32_t* values) {
 
     hwc_context_t* ctx = (hwc_context_t*)(dev);
-    disp = getHWCDpy(ctx, disp);
+    disp = getDpyforExternalDisplay(ctx, disp);
     //If hotpluggable displays(i.e, HDMI, WFD) are inactive return error
     if( (disp != HWC_DISPLAY_PRIMARY) && !ctx->dpyAttr[disp].connected) {
         return -1;
diff --git a/libhwcomposer/hwc_uevents.cpp b/libhwcomposer/hwc_uevents.cpp
index 5590798..ecb2104 100644
--- a/libhwcomposer/hwc_uevents.cpp
+++ b/libhwcomposer/hwc_uevents.cpp
@@ -226,20 +226,20 @@
             ctx->dpyAttr[dpy].connected = true;
             ctx->dpyAttr[dpy].isConfiguring = true;
 
-            if(dpy == HWC_DISPLAY_VIRTUAL) {
+            if(dpy == HWC_DISPLAY_EXTERNAL ||
+               ctx->mVirtualonExtActive) {
+                /* External display is HDMI or non-hybrid WFD solution */
+                ALOGE_IF(UEVENT_DEBUG, "%s: Sending EXTERNAL_OFFLINE ONLINE"
+                         "hotplug event", __FUNCTION__);
+                ctx->proc->hotplug(ctx->proc,HWC_DISPLAY_EXTERNAL,
+                                   EXTERNAL_ONLINE);
+            } else {
                 /* We wont be getting unblank for VIRTUAL DISPLAY and its
                  * always guaranteed from WFD stack that CONNECT uevent for
                  * VIRTUAL DISPLAY will be triggered before creating
                  * surface for the same. */
                 ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isActive = true;
             }
-            if(dpy == HWC_DISPLAY_EXTERNAL ||
-               ctx->mVirtualonExtActive) {
-                ALOGE_IF(UEVENT_DEBUG, "%s: Sending EXTERNAL_OFFLINE ONLINE"
-                         "hotplug event", __FUNCTION__);
-                ctx->proc->hotplug(ctx->proc,HWC_DISPLAY_EXTERNAL,
-                                   EXTERNAL_ONLINE);
-            }
             break;
         }
         case EXTERNAL_PAUSE: