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
This commit is contained in:
@@ -99,6 +99,8 @@ int ExternalDisplay::configureHDMIDisplay() {
|
|||||||
setResolution(mode);
|
setResolution(mode);
|
||||||
setDpyHdmiAttr();
|
setDpyHdmiAttr();
|
||||||
setExternalDisplay(true, mHdmiFbNum);
|
setExternalDisplay(true, mHdmiFbNum);
|
||||||
|
// set system property
|
||||||
|
property_set("hw.hdmiON", "1");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,6 +130,8 @@ int ExternalDisplay::teardownHDMIDisplay() {
|
|||||||
closeFrameBuffer();
|
closeFrameBuffer();
|
||||||
resetInfo();
|
resetInfo();
|
||||||
setExternalDisplay(false);
|
setExternalDisplay(false);
|
||||||
|
// unset system property
|
||||||
|
property_set("hw.hdmiON", "0");
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -142,29 +146,17 @@ int ExternalDisplay::teardownWFDDisplay() {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExternalDisplay::processUEventOnline(const char *str) {
|
int ExternalDisplay::ignoreRequest(const char *str) {
|
||||||
const char *s1 = str + strlen("change@/devices/virtual/switch/");
|
const char *s1 = str + strlen("change@/devices/virtual/switch/");
|
||||||
if(!strncmp(s1,"hdmi",strlen(s1))) {
|
if(!strncmp(s1,"wfd",strlen(s1))) {
|
||||||
// hdmi online event..!
|
if(mConnectedFbNum == mHdmiFbNum) {
|
||||||
configureHDMIDisplay();
|
ALOGE("Ignore wfd event when HDMI is active");
|
||||||
// set system property
|
return true;
|
||||||
property_set("hw.hdmiON", "1");
|
}
|
||||||
}else if(!strncmp(s1,"wfd",strlen(s1))) {
|
|
||||||
// wfd online event..!
|
|
||||||
configureWFDDisplay();
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExternalDisplay::processUEventOffline(const char *str) {
|
|
||||||
const char *s1 = str + strlen("change@/devices/virtual/switch/");
|
|
||||||
if(!strncmp(s1,"hdmi",strlen(s1))) {
|
|
||||||
teardownHDMIDisplay();
|
|
||||||
// unset system property
|
|
||||||
property_set("hw.hdmiON", "0");
|
|
||||||
}else if(!strncmp(s1,"wfd",strlen(s1))) {
|
|
||||||
teardownWFDDisplay();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ExternalDisplay::ExternalDisplay(hwc_context_t* ctx):mFd(-1),
|
ExternalDisplay::ExternalDisplay(hwc_context_t* ctx):mFd(-1),
|
||||||
mCurrentMode(-1), mConnected(0), mConnectedFbNum(0), mModeCount(0),
|
mCurrentMode(-1), mConnected(0), mConnectedFbNum(0), mModeCount(0),
|
||||||
|
|||||||
@@ -47,11 +47,16 @@ public:
|
|||||||
void setExternalDisplay(bool connected, int extFbNum = 0);
|
void setExternalDisplay(bool connected, int extFbNum = 0);
|
||||||
bool isExternalConnected() { return mConnected;};
|
bool isExternalConnected() { return mConnected;};
|
||||||
void setExtDpyNum(int extDpyNum) { mExtDpyNum = extDpyNum;};
|
void setExtDpyNum(int extDpyNum) { mExtDpyNum = extDpyNum;};
|
||||||
|
int getExternalType() {return mConnectedFbNum;};
|
||||||
|
bool isWFDActive() {return (mConnectedFbNum == mWfdFbNum);};
|
||||||
void setHPD(uint32_t startEnd);
|
void setHPD(uint32_t startEnd);
|
||||||
void setEDIDMode(int resMode);
|
void setEDIDMode(int resMode);
|
||||||
void setActionSafeDimension(int w, int h);
|
void setActionSafeDimension(int w, int h);
|
||||||
void processUEventOnline(const char *str);
|
int ignoreRequest(const char *str);
|
||||||
void processUEventOffline(const char *str);
|
int configureHDMIDisplay();
|
||||||
|
int configureWFDDisplay();
|
||||||
|
int teardownHDMIDisplay();
|
||||||
|
int teardownWFDDisplay();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void readCEUnderscanInfo();
|
void readCEUnderscanInfo();
|
||||||
@@ -72,10 +77,6 @@ private:
|
|||||||
void setDpyWfdAttr();
|
void setDpyWfdAttr();
|
||||||
void getAttrForMode(int& width, int& height, int& fps);
|
void getAttrForMode(int& width, int& height, int& fps);
|
||||||
void updateExtDispDevFbIndex();
|
void updateExtDispDevFbIndex();
|
||||||
int configureHDMIDisplay();
|
|
||||||
int configureWFDDisplay();
|
|
||||||
int teardownHDMIDisplay();
|
|
||||||
int teardownWFDDisplay();
|
|
||||||
int getExtFbNum(int &fbNum);
|
int getExtFbNum(int &fbNum);
|
||||||
|
|
||||||
mutable android::Mutex mExtDispLock;
|
mutable android::Mutex mExtDispLock;
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
#include "external.h"
|
#include "external.h"
|
||||||
|
|
||||||
namespace qhwc {
|
namespace qhwc {
|
||||||
|
#define HWC_UEVENT_SWITCH_STR "change@/devices/virtual/switch/"
|
||||||
#define HWC_UEVENT_THREAD_NAME "hwcUeventThread"
|
#define HWC_UEVENT_THREAD_NAME "hwcUeventThread"
|
||||||
|
|
||||||
/* External Display states */
|
/* External Display states */
|
||||||
@@ -51,6 +51,32 @@ static bool isHDMI(const char* str)
|
|||||||
return false;
|
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)
|
static void handle_uevent(hwc_context_t* ctx, const char* udata, int len)
|
||||||
{
|
{
|
||||||
int vsync = 0;
|
int vsync = 0;
|
||||||
@@ -65,7 +91,6 @@ static void handle_uevent(hwc_context_t* ctx, const char* udata, int len)
|
|||||||
qdutils::COMPOSITION_TYPE_C2D)) {
|
qdutils::COMPOSITION_TYPE_C2D)) {
|
||||||
usecopybit = true;
|
usecopybit = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!strcasestr("change@/devices/virtual/switch/hdmi", str) &&
|
if(!strcasestr("change@/devices/virtual/switch/hdmi", str) &&
|
||||||
!strcasestr("change@/devices/virtual/switch/wfd", str)) {
|
!strcasestr("change@/devices/virtual/switch/wfd", str)) {
|
||||||
ALOGD_IF(UEVENT_DEBUG, "%s: Not Ext Disp Event ", __FUNCTION__);
|
ALOGD_IF(UEVENT_DEBUG, "%s: Not Ext Disp Event ", __FUNCTION__);
|
||||||
@@ -84,9 +109,6 @@ static void handle_uevent(hwc_context_t* ctx, const char* udata, int len)
|
|||||||
|
|
||||||
int dpy = isHDMI(str) ? HWC_DISPLAY_EXTERNAL : extDpyNum;
|
int dpy = isHDMI(str) ? HWC_DISPLAY_EXTERNAL : extDpyNum;
|
||||||
|
|
||||||
// update extDpyNum
|
|
||||||
ctx->mExtDisplay->setExtDpyNum(dpy);
|
|
||||||
|
|
||||||
// parse HDMI/WFD switch state for connect/disconnect
|
// parse HDMI/WFD switch state for connect/disconnect
|
||||||
// for HDMI:
|
// for HDMI:
|
||||||
// The event will be of the form:
|
// The event will be of the form:
|
||||||
@@ -106,30 +128,33 @@ static void handle_uevent(hwc_context_t* ctx, const char* udata, int len)
|
|||||||
if (str - udata >= len)
|
if (str - udata >= len)
|
||||||
break;
|
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) {
|
switch(connected) {
|
||||||
case EXTERNAL_OFFLINE:
|
case EXTERNAL_OFFLINE:
|
||||||
{ // disconnect event
|
{ // disconnect event
|
||||||
ctx->mExtDisplay->processUEventOffline(udata);
|
const char *s1 = udata + strlen(HWC_UEVENT_SWITCH_STR);
|
||||||
if(ctx->mFBUpdate[dpy]) {
|
if(!strncmp(s1,"hdmi",strlen(s1))) {
|
||||||
Locker::Autolock _l(ctx->mExtSetLock);
|
ctx->mExtDisplay->teardownHDMIDisplay();
|
||||||
delete ctx->mFBUpdate[dpy];
|
}else if(!strncmp(s1,"wfd",strlen(s1))) {
|
||||||
ctx->mFBUpdate[dpy] = NULL;
|
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",
|
ALOGD("%s sending hotplug: connected = %d and dpy:%d",
|
||||||
__FUNCTION__, connected, dpy);
|
__FUNCTION__, connected, dpy);
|
||||||
ctx->dpyAttr[dpy].connected = false;
|
ctx->dpyAttr[dpy].connected = false;
|
||||||
Locker::Autolock _l(ctx->mExtSetLock);
|
|
||||||
//hwc comp could be on
|
//hwc comp could be on
|
||||||
ctx->proc->hotplug(ctx->proc, dpy, connected);
|
ctx->proc->hotplug(ctx->proc, dpy, connected);
|
||||||
break;
|
break;
|
||||||
@@ -137,14 +162,38 @@ static void handle_uevent(hwc_context_t* ctx, const char* udata, int len)
|
|||||||
case EXTERNAL_ONLINE:
|
case EXTERNAL_ONLINE:
|
||||||
{ // connect case
|
{ // connect case
|
||||||
ctx->mExtDispConfiguring = true;
|
ctx->mExtDispConfiguring = true;
|
||||||
ctx->mExtDisplay->processUEventOnline(udata);
|
const char *s1 = udata + strlen(HWC_UEVENT_SWITCH_STR);
|
||||||
ctx->mFBUpdate[dpy] =
|
if(!strncmp(s1,"hdmi",strlen(s1))) {
|
||||||
IFBUpdate::getObject(ctx->dpyAttr[dpy].xres, dpy);
|
// hdmi online event..!
|
||||||
ctx->mVidOv[dpy] =
|
// check if WFD is configured
|
||||||
IVideoOverlay::getObject(ctx->dpyAttr[dpy].xres, dpy);
|
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;
|
ctx->dpyAttr[dpy].isPause = false;
|
||||||
if(usecopybit)
|
setup(ctx, dpy, usecopybit);
|
||||||
ctx->mCopyBit[dpy] = new CopyBit();
|
|
||||||
ALOGD("%s sending hotplug: connected = %d", __FUNCTION__,
|
ALOGD("%s sending hotplug: connected = %d", __FUNCTION__,
|
||||||
connected);
|
connected);
|
||||||
ctx->dpyAttr[dpy].connected = true;
|
ctx->dpyAttr[dpy].connected = true;
|
||||||
|
|||||||
Reference in New Issue
Block a user