hwc: Add binder API to disable screen updates

When the display is put in calibration mode by postprocessing
tools such as QDCM, the pipes are taken over and updates need to
be blocked.

Change-Id: I413caf40ad0a7ccdd43a3167bd7e3415e8bc8b55
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index c96eb1e..3b66fae 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -257,7 +257,8 @@
     bool fbComp = false;
     if (LIKELY(list && list->numHwLayers > 1) &&
             (ctx->dpyAttr[dpy].isActive ||
-             ctx->mHDMIDisplay->isHDMIPrimaryDisplay())) {
+             ctx->mHDMIDisplay->isHDMIPrimaryDisplay())
+            && !ctx->dpyAttr[dpy].isPause) {
 
         // When HDMI is primary we should rely on the first valid
         // draw call in order to activate the display
@@ -585,7 +586,8 @@
     ATRACE_CALL();
     int ret = 0;
     const int dpy = HWC_DISPLAY_PRIMARY;
-    if (LIKELY(list) && ctx->dpyAttr[dpy].isActive) {
+    if (LIKELY(list) && ctx->dpyAttr[dpy].isActive
+            && !ctx->dpyAttr[dpy].isPause) {
         size_t last = list->numHwLayers - 1;
         hwc_layer_1_t *fbLayer = &list->hwLayers[last];
         int fd = -1; //FenceFD from the Copybit(valid in async mode)
diff --git a/libhwcomposer/hwc_qclient.cpp b/libhwcomposer/hwc_qclient.cpp
index add5dc8..1a29b89 100644
--- a/libhwcomposer/hwc_qclient.cpp
+++ b/libhwcomposer/hwc_qclient.cpp
@@ -313,6 +313,23 @@
     return NO_ERROR;
 }
 
+static void toggleScreenUpdate(hwc_context_t* ctx, uint32_t on) {
+    ALOGD("%s: toggle update: %d", __FUNCTION__, on);
+    Locker::Autolock _sl(ctx->mDrawLock);
+    if (on == 0) {
+        ctx->dpyAttr[HWC_DISPLAY_PRIMARY].isPause = true;
+        ctx->mOverlay->configBegin();
+        ctx->mOverlay->configDone();
+        ctx->mRotMgr->clear();
+        if(!Overlay::displayCommit(ctx->dpyAttr[0].fd)) {
+            ALOGE("%s: Display commit failed", __FUNCTION__);
+        }
+    } else {
+        ctx->dpyAttr[HWC_DISPLAY_PRIMARY].isPause = false;
+        ctx->proc->invalidate(ctx->proc);
+    }
+}
+
 status_t QClient::notifyCallback(uint32_t command, const Parcel* inParcel,
         Parcel* outParcel) {
     status_t ret = NO_ERROR;
@@ -369,6 +386,9 @@
         case IQService::CONFIGURE_DYN_REFRESH_RATE:
             configureDynRefreshRate(mHwcContext, inParcel);
             break;
+        case IQService::TOGGLE_SCREEN_UPDATE:
+            toggleScreenUpdate(mHwcContext, inParcel->readInt32());
+            break;
         default:
             ret = NO_ERROR;
     }
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 286ae22..7b209c6 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -96,7 +96,7 @@
     //It should be active also. (UNBLANKED)
     bool isActive;
     // In pause state, composition is bypassed
-    // used for WFD displays only
+    // used for WFD displays and in QDCM calibration mode
     bool isPause;
     // To trigger padding round to clean up mdp
     // pipes
diff --git a/libqservice/IQService.h b/libqservice/IQService.h
index f28293d..ef47475 100644
--- a/libqservice/IQService.h
+++ b/libqservice/IQService.h
@@ -58,6 +58,7 @@
         /* Enable/Disable/Set refresh rate dynamically */
         CONFIGURE_DYN_REFRESH_RATE = 18,
         SET_PARTIAL_UPDATE = 19,   // Preference on partial update feature
+        TOGGLE_SCREEN_UPDATE = 20, // Provides ability to disable screen updates
         COMMAND_LIST_END = 400,
     };
 
diff --git a/libqservice/QServiceUtils.h b/libqservice/QServiceUtils.h
index 5b61c8e..71277e8 100644
--- a/libqservice/QServiceUtils.h
+++ b/libqservice/QServiceUtils.h
@@ -74,6 +74,10 @@
     return sendSingleParam(qService::IQService::SCREEN_REFRESH, 1);
 }
 
+inline android::status_t toggleScreenUpdate(uint32_t on) {
+    return sendSingleParam(qService::IQService::TOGGLE_SCREEN_UPDATE, on);
+}
+
 inline android::status_t setPartialUpdate(uint32_t enable) {
     return sendSingleParam(qService::IQService::SET_PARTIAL_UPDATE, enable);
 }