Display and wfd synchronization during teardown

* Provide a binder interface call for wfd module
to inform display about the start/stop/pause/resume
of wfd session.

* This is needed for wfd-hdmi synchronization in
case of v4l2 wfd solution. If hdmi is plugged
in during v4l2 wfd session, display-hal waits in
uevent thread for wfd teardown notification from
wfd module, before going ahead with configuring
external display.

* For VDS WFD solution, display-hal waits in uevent
thread for wfd-teardown to be signalled from
the composition thread.

Change-Id: I9514cb5bc7ff81de0b5dd4cdf66d8286a64ba094
diff --git a/libhwcomposer/hwc_uevents.cpp b/libhwcomposer/hwc_uevents.cpp
index e1f7827..fed6f3c 100644
--- a/libhwcomposer/hwc_uevents.cpp
+++ b/libhwcomposer/hwc_uevents.cpp
@@ -39,14 +39,6 @@
 #define HWC_UEVENT_SWITCH_STR  "change@/devices/virtual/switch/"
 #define HWC_UEVENT_THREAD_NAME "hwcUeventThread"
 
-/* External Display states */
-enum {
-    EXTERNAL_OFFLINE = 0,
-    EXTERNAL_ONLINE,
-    EXTERNAL_PAUSE,
-    EXTERNAL_RESUME
-};
-
 static void setup(hwc_context_t* ctx, int dpy)
 {
     ctx->mFBUpdate[dpy] = IFBUpdate::getObject(ctx, dpy);
@@ -145,9 +137,24 @@
             ctx->mVirtualonExtActive = false;
         }
     }
-    /* Wait for few frames for SF to tear down the WFD session. */
-    usleep(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period
-            * 2 / 1000);
+
+    if(ctx->mVDSEnabled) {
+        ctx->mWfdSyncLock.lock();
+        ALOGD_IF(HWC_WFDDISPSYNC_LOG,
+                 "%s: Waiting for wfd-teardown to be signalled",__FUNCTION__);
+        ctx->mWfdSyncLock.wait();
+        ALOGD_IF(HWC_WFDDISPSYNC_LOG,
+                 "%s: Teardown signalled. Completed waiting in uevent thread",
+                 __FUNCTION__);
+        ctx->mWfdSyncLock.unlock();
+    } else {
+        /*TODO: Remove this else block and have wait rather than usleep
+          once wfd module issues binder call on teardown.*/
+
+        /* For now, Wait for few frames for SF to tear down the WFD session.*/
+        usleep(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period
+               * 2 / 1000);
+    }
 }
 
 static void handle_uevent(hwc_context_t* ctx, const char* udata, int len)
@@ -166,7 +173,7 @@
 
     int switch_state = getConnectedState(udata, len);
 
-    ALOGE_IF(UEVENT_DEBUG,"%s: uevent recieved: %s switch state: %d",
+    ALOGE_IF(UEVENT_DEBUG,"%s: uevent received: %s switch state: %d",
              __FUNCTION__,udata, switch_state);
 
     switch(switch_state) {