hwc: Processing of HDMI connection request when WFD is active

  when HDMI is connected during active WFD session, teardown
  WFD and process HDMI connection request.

CRs-Fixed: 442226
Change-Id: I4b22ff9f1ab3175bab47babdaf040cb2289ebe4d
diff --git a/libhwcomposer/hwc_uevents.cpp b/libhwcomposer/hwc_uevents.cpp
index d27128e..c6d00cb 100644
--- a/libhwcomposer/hwc_uevents.cpp
+++ b/libhwcomposer/hwc_uevents.cpp
@@ -33,7 +33,7 @@
 #include "external.h"
 
 namespace qhwc {
-
+#define HWC_UEVENT_SWITCH_STR  "change@/devices/virtual/switch/"
 #define HWC_UEVENT_THREAD_NAME "hwcUeventThread"
 
 /* External Display states */
@@ -51,6 +51,32 @@
     return false;
 }
 
+static void setup(hwc_context_t* ctx, int dpy, bool usecopybit)
+{
+    ctx->mFBUpdate[dpy] =
+            IFBUpdate::getObject(ctx->dpyAttr[dpy].xres, dpy);
+    if(usecopybit)
+        ctx->mCopyBit[dpy] = new CopyBit();
+    ctx->mVidOv[dpy] =
+            IVideoOverlay::getObject(ctx->dpyAttr[dpy].xres, dpy);
+}
+
+static void clear(hwc_context_t* ctx, int dpy)
+{
+    if(ctx->mFBUpdate[dpy]) {
+        delete ctx->mFBUpdate[dpy];
+        ctx->mFBUpdate[dpy] = NULL;
+    }
+    if(ctx->mCopyBit[dpy]){
+        delete ctx->mCopyBit[dpy];
+        ctx->mCopyBit[dpy] = NULL;
+    }
+    if(ctx->mVidOv[dpy]) {
+        delete ctx->mVidOv[dpy];
+        ctx->mVidOv[dpy] = NULL;
+    }
+}
+
 static void handle_uevent(hwc_context_t* ctx, const char* udata, int len)
 {
     int vsync = 0;
@@ -65,7 +91,6 @@
                            qdutils::COMPOSITION_TYPE_C2D)) {
         usecopybit = true;
     }
-
     if(!strcasestr("change@/devices/virtual/switch/hdmi", str) &&
        !strcasestr("change@/devices/virtual/switch/wfd", str)) {
         ALOGD_IF(UEVENT_DEBUG, "%s: Not Ext Disp Event ", __FUNCTION__);
@@ -84,9 +109,6 @@
 
     int dpy = isHDMI(str) ? HWC_DISPLAY_EXTERNAL : extDpyNum;
 
-    // update extDpyNum
-    ctx->mExtDisplay->setExtDpyNum(dpy);
-
     // parse HDMI/WFD switch state for connect/disconnect
     // for HDMI:
     // The event will be of the form:
@@ -106,30 +128,33 @@
         if (str - udata >= len)
             break;
     }
+    ALOGD_IF(UEVENT_DEBUG, "Received str:%s",udata);
 
+    if(connected != EXTERNAL_ONLINE) {
+        if(ctx->mExtDisplay->ignoreRequest(udata)) {
+            ALOGD_IF(UEVENT_DEBUG,"No need to process this connection request"
+                                  "str:%s",udata);
+           ctx->dpyAttr[dpy].isActive = true;
+           return;
+        }
+    }
+
+    // update extDpyNum
+    ctx->mExtDisplay->setExtDpyNum(dpy);
     switch(connected) {
         case EXTERNAL_OFFLINE:
             {   // disconnect event
-                ctx->mExtDisplay->processUEventOffline(udata);
-                if(ctx->mFBUpdate[dpy]) {
-                    Locker::Autolock _l(ctx->mExtSetLock);
-                    delete ctx->mFBUpdate[dpy];
-                    ctx->mFBUpdate[dpy] = NULL;
+                const char *s1 = udata + strlen(HWC_UEVENT_SWITCH_STR);
+                if(!strncmp(s1,"hdmi",strlen(s1))) {
+                    ctx->mExtDisplay->teardownHDMIDisplay();
+                }else if(!strncmp(s1,"wfd",strlen(s1))) {
+                    ctx->mExtDisplay->teardownWFDDisplay();
                 }
-                if(ctx->mVidOv[dpy]) {
-                    Locker::Autolock _l(ctx->mExtSetLock);
-                    delete ctx->mVidOv[dpy];
-                    ctx->mVidOv[dpy] = NULL;
-                }
-                if(ctx->mCopyBit[dpy]){
-                    Locker::Autolock _l(ctx->mExtSetLock);
-                    delete ctx->mCopyBit[dpy];
-                    ctx->mCopyBit[dpy] = NULL;
-                }
+                Locker::Autolock _l(ctx->mExtSetLock);
+                clear(ctx, dpy);
                 ALOGD("%s sending hotplug: connected = %d and dpy:%d",
                       __FUNCTION__, connected, dpy);
                 ctx->dpyAttr[dpy].connected = false;
-                Locker::Autolock _l(ctx->mExtSetLock);
                 //hwc comp could be on
                 ctx->proc->hotplug(ctx->proc, dpy, connected);
                 break;
@@ -137,14 +162,38 @@
         case EXTERNAL_ONLINE:
             {   // connect case
                 ctx->mExtDispConfiguring = true;
-                ctx->mExtDisplay->processUEventOnline(udata);
-                ctx->mFBUpdate[dpy] =
-                        IFBUpdate::getObject(ctx->dpyAttr[dpy].xres, dpy);
-                ctx->mVidOv[dpy] =
-                        IVideoOverlay::getObject(ctx->dpyAttr[dpy].xres, dpy);
+                const char *s1 = udata + strlen(HWC_UEVENT_SWITCH_STR);
+                if(!strncmp(s1,"hdmi",strlen(s1))) {
+                    // hdmi online event..!
+                    // check if WFD is configured
+                    if(ctx->mExtDisplay->isWFDActive()) {
+                        ALOGD_IF(UEVENT_DEBUG,"Received HDMI connection request"
+                                "when WFD is active");
+                        // teardown Active WFD Display
+                        ctx->mExtDisplay->teardownWFDDisplay();
+                        {
+                            Locker::Autolock _l(ctx->mExtSetLock);
+                            clear(ctx, dpy);
+                            //send hotplug disconnect event
+                            ALOGD_IF(UEVENT_DEBUG, "sending hotplug: disconnect"
+                                    "for WFD");
+                            // hwc comp could be on
+                            ctx->proc->hotplug(ctx->proc, dpy, EXTERNAL_OFFLINE);
+                        }
+                        //Invalidate
+                        ctx->proc->invalidate(ctx->proc);
+                        //wait for 1 second
+                        ALOGE_IF(UEVENT_DEBUG, "wait for 1 second -- padding"
+                                "round");
+                        sleep(1);
+                    }
+                    ctx->mExtDisplay->configureHDMIDisplay();
+                } else if(!strncmp(s1,"wfd",strlen(s1))) {
+                    // wfd online event..!
+                    ctx->mExtDisplay->configureWFDDisplay();
+                }
                 ctx->dpyAttr[dpy].isPause = false;
-                if(usecopybit)
-                    ctx->mCopyBit[dpy] = new CopyBit();
+                setup(ctx, dpy, usecopybit);
                 ALOGD("%s sending hotplug: connected = %d", __FUNCTION__,
                         connected);
                 ctx->dpyAttr[dpy].connected = true;