display: Add HDMI CEC HAL

Implement the spec as per
hardware/libhardware/include/hardware/hdmi_cec.h

Change-Id: I02e1ba9deee1007b7e5922c363b9f5d6c6ad82a9
diff --git a/libhwcomposer/hwc_uevents.cpp b/libhwcomposer/hwc_uevents.cpp
index c6179e4..e282b53 100644
--- a/libhwcomposer/hwc_uevents.cpp
+++ b/libhwcomposer/hwc_uevents.cpp
@@ -125,6 +125,9 @@
                 ctx->proc->hotplug(ctx->proc, dpy, EXTERNAL_OFFLINE);
             }
 
+            // Report Hotplug via CEC HAL
+            ctx->mQService->onHdmiHotplug((int)ctx->dpyAttr[dpy].connected);
+
             //On 8994, 8992 due to hardware limitations, we disable bwc
             //when HDMI intf is active
             if((qdutils::MDPVersion::getInstance().is8994() or
@@ -213,6 +216,7 @@
             /* External display is HDMI */
             ALOGI("%s: Sending EXTERNAL ONLINE event", __FUNCTION__);
             ctx->proc->hotplug(ctx->proc, dpy, EXTERNAL_ONLINE);
+            ctx->mQService->onHdmiHotplug(ctx->dpyAttr[dpy].connected);
             break;
         }
     default:
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 05ab503..f43b9df 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -376,14 +376,15 @@
     //independent process as well.
     QService::init();
     sp<IQClient> client = new QClient(ctx);
-    android::sp<qService::IQService> qservice_sp = interface_cast<IQService>(
+    sp<IQService> iqs = interface_cast<IQService>(
             defaultServiceManager()->getService(
             String16("display.qservice")));
-    if (qservice_sp.get()) {
-      qservice_sp->connect(client);
+    if (iqs.get()) {
+      iqs->connect(client);
+      ctx->mQService = reinterpret_cast<QService* >(iqs.get());
     } else {
       ALOGE("%s: Failed to acquire service pointer", __FUNCTION__);
-      return ;
+      return;
     }
 
     // Initialize device orientation to its default orientation
@@ -479,7 +480,10 @@
         ctx->mAD = NULL;
     }
 
-
+    if(ctx->mQService) {
+        delete ctx->mQService;
+        ctx->mQService = NULL;
+    }
 }
 
 //Helper to roundoff the refreshrates
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index f11eed5..23157d4 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -35,6 +35,7 @@
 #include <overlayUtils.h>
 #include <overlayRotator.h>
 #include <EGL/egl.h>
+#include <QService.h>
 
 
 #define ALIGN_TO(x, align)     (((x) + ((align)-1)) & ~((align)-1))
@@ -687,6 +688,8 @@
     bool mHPDEnabled;
     //Used to notify that boot has completed
     bool mBootAnimCompleted;
+    // Display binder service
+    qService::QService* mQService;
 };
 
 namespace qhwc {
diff --git a/libhwcomposer/hwc_vsync.cpp b/libhwcomposer/hwc_vsync.cpp
index 89f8044..d9dc27c 100644
--- a/libhwcomposer/hwc_vsync.cpp
+++ b/libhwcomposer/hwc_vsync.cpp
@@ -56,7 +56,8 @@
     return ret;
 }
 
-static void handle_vsync_event(hwc_context_t* ctx, int dpy, char *data)
+static void handle_vsync_event(hwc_context_t* ctx, int dpy, char *data,
+        ssize_t len __unused)
 {
     // extract timestamp
     uint64_t timestamp = 0;
@@ -69,7 +70,8 @@
     ctx->proc->vsync(ctx->proc, dpy, timestamp);
 }
 
-static void handle_blank_event(hwc_context_t* ctx, int dpy, char *data)
+static void handle_blank_event(hwc_context_t* ctx, int dpy, char *data,
+        ssize_t len __unused)
 {
     if (!strncmp(data, PANEL_ON_STR, strlen(PANEL_ON_STR))) {
         unsigned long int poweron = strtoul(data + strlen(PANEL_ON_STR), NULL, 0);
@@ -80,7 +82,8 @@
     }
 }
 
-static void handle_thermal_event(hwc_context_t* ctx, int dpy, char *data)
+static void handle_thermal_event(hwc_context_t* ctx, int dpy, char *data,
+        ssize_t len __unused)
 {
     // extract thermal level
     uint64_t thermalLevel = 0;
@@ -95,15 +98,23 @@
         ctx->mThermalBurstMode = false;
 }
 
+static void handle_cec_event(hwc_context_t* ctx, int dpy, char *data,
+        ssize_t len)
+{
+    ALOGD("%s: Got CEC event from driver dpy:%d", __FUNCTION__, dpy);
+    ctx->mQService->onCECMessageReceived(data, len);
+}
+
 struct event {
     const char* name;
-    void (*callback)(hwc_context_t* ctx, int dpy, char *data);
+    void (*callback)(hwc_context_t* ctx, int dpy, char *data, ssize_t len);
 };
 
 struct event event_list[] =  {
     { "vsync_event", handle_vsync_event },
     { "show_blank_event", handle_blank_event },
     { "msm_fb_thermal_level", handle_thermal_event },
+    { "cec/rd_msg", handle_cec_event },
 };
 
 #define num_events ARRAY_LENGTH(event_list)
@@ -185,7 +196,7 @@
                                 continue;
                             }
                             vdata[len] = '\0';
-                            event_list[ev].callback(ctx, dpy, vdata);
+                            event_list[ev].callback(ctx, dpy, vdata, len);
                         }
                     }
                 }