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;