h/q/d: Add binder-api support to change refresh-rate.

** Now, there are two ways for the clients to request
change in the refresh-rate of the target.
(a) Using metadata of the input-buffer.
(b) Using binder api added as part of this change.

** configureDynRefreshRate binder api provides three
op-modes which can be used as following:

(a) "DISABLE_METADATA_DYN_REFRESH_RATE" can be used by the
clients, to disallow display-hal from honoring refresh-rate
change requests, made by video-clients using the metadata.

For ex: This can be used during streaming use-cases
(Dash-playback, playback at WFD-sink,etc) where the idea
is not to change the refresh-rate, though video-client
requests for it using metadata, as video-clients cannot
distinguish between streaming and non-streaming usecases.

Usage:
adb shell service call display.qservice 18 i32 0 i32 0

(b) "ENABLE_METADATA_DYN_REFRESH_RATE" can be used by the
clients after DISABLE_METADATA_DYN_REFRESH_RATE, to once
again allow display-hal to be able to change refresh-rate
based on requests made by the video-clients using metadata.

For ex: This can be used by clients( Dash-playback,
WFD, etc) once they are done with their use-case.
WFD-framework will also use this when the wfd-session is
paused.

Usage:
adb shell service call display.qservice 18 i32 1 i32 0

(c) "SET_BINDER_DYN_REFRESH_RATE" can be used by the clients
to change the refresh-rate of the target using binder-api,
provided they have disallowed display from honoring the
refresh-rate requests made using metadata.

In other words, changing refresh-rate through this binder
api and using metadata approach cannot co-exist together.

Usage:
adb shell service call display.qservice 18 i32 2 i32 45
-- The refresh-rate set here will correspond to 45fps.

** Added property "persist.metadata_dynfps.disable" that
can be used by OEM's, to disable setting of refresh-rate
using the metadata.

Change-Id: I767fa174dcf1cfd061a578e96cd68af28e7dd36b
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index aa7783c..d7f31da 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -1978,7 +1978,8 @@
 
 #ifdef DYNAMIC_FPS
     //For primary display, set the dynamic refreshrate
-    if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported()) {
+    if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported() &&
+                                        ctx->mUseMetaDataRefreshRate) {
         FrameInfo frame;
         frame.reset(mCurrentFrame.layerCount);
         memset(&frame.drop, 0, sizeof(frame.drop));
diff --git a/libhwcomposer/hwc_qclient.cpp b/libhwcomposer/hwc_qclient.cpp
index 398995a..b0ebb3a 100644
--- a/libhwcomposer/hwc_qclient.cpp
+++ b/libhwcomposer/hwc_qclient.cpp
@@ -34,6 +34,7 @@
 #include <hwc_mdpcomp.h>
 #include <hwc_virtual.h>
 #include <overlay.h>
+#include <display_config.h>
 
 #define QCLIENT_DEBUG 0
 
@@ -175,13 +176,13 @@
                                         dpy, getExternalDisplayState(status));
 
     if(dpy > HWC_DISPLAY_PRIMARY && dpy <= HWC_DISPLAY_VIRTUAL) {
-        if(dpy == HWC_DISPLAY_VIRTUAL && status == EXTERNAL_OFFLINE) {
+        if(dpy == HWC_DISPLAY_VIRTUAL && status == qdutils::EXTERNAL_OFFLINE) {
             ctx->mWfdSyncLock.lock();
             ctx->mWfdSyncLock.signal();
             ctx->mWfdSyncLock.unlock();
-        } else if(status == EXTERNAL_PAUSE) {
+        } else if(status == qdutils::EXTERNAL_PAUSE) {
             handle_pause(ctx, dpy);
-        } else if(status == EXTERNAL_RESUME) {
+        } else if(status == qdutils::EXTERNAL_RESUME) {
             handle_resume(ctx, dpy);
         }
     } else {
@@ -263,6 +264,48 @@
     }
 }
 
+static void configureDynRefreshRate(hwc_context_t* ctx,
+                                    const Parcel* inParcel) {
+    uint32_t op = (uint32_t)inParcel->readInt32();
+    uint32_t refresh_rate = (uint32_t)inParcel->readInt32();
+    MDPVersion& mdpHw = MDPVersion::getInstance();
+    uint32_t dpy = HWC_DISPLAY_PRIMARY;
+
+    if(mdpHw.isDynFpsSupported()) {
+        Locker::Autolock _sl(ctx->mDrawLock);
+
+        switch (op) {
+        case DISABLE_METADATA_DYN_REFRESH_RATE:
+            ctx->mUseMetaDataRefreshRate = false;
+            setRefreshRate(ctx, dpy, ctx->dpyAttr[dpy].refreshRate);
+            break;
+        case ENABLE_METADATA_DYN_REFRESH_RATE:
+            ctx->mUseMetaDataRefreshRate = true;
+            setRefreshRate(ctx, dpy, ctx->dpyAttr[dpy].refreshRate);
+            break;
+        case SET_BINDER_DYN_REFRESH_RATE:
+            if(ctx->mUseMetaDataRefreshRate)
+                ALOGW("%s: Ignoring binder request to change refresh-rate",
+                      __FUNCTION__);
+            else {
+                uint32_t rate = roundOff(refresh_rate);
+                if((rate >= mdpHw.getMinFpsSupported() &&
+                    rate <= mdpHw.getMaxFpsSupported())) {
+                    setRefreshRate(ctx, dpy, rate);
+                } else {
+                    ALOGE("%s: Requested refresh-rate should be between \
+                          (%d) and (%d). Given (%d)", __FUNCTION__,
+                          mdpHw.getMinFpsSupported(),
+                          mdpHw.getMaxFpsSupported(), rate);
+                }
+            }
+            break;
+        default:
+            ALOGE("%s: Invalid op %d",__FUNCTION__,op);
+        }
+    }
+}
+
 status_t QClient::notifyCallback(uint32_t command, const Parcel* inParcel,
         Parcel* outParcel) {
     status_t ret = NO_ERROR;
@@ -314,6 +357,9 @@
         case IQService::TOGGLE_BWC:
             toggleBWC(mHwcContext, inParcel);
             break;
+        case IQService::CONFIGURE_DYN_REFRESH_RATE:
+            configureDynRefreshRate(mHwcContext, inParcel);
+            break;
         default:
             ret = NO_ERROR;
     }
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 916fbc7..f964212 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -401,6 +401,12 @@
         ctx->mWindowboxFeature = true;
     }
 
+    ctx->mUseMetaDataRefreshRate = true;
+    if(property_get("persist.metadata_dynfps.disable", value, "false")
+            && !strcmp(value, "true")) {
+        ctx->mUseMetaDataRefreshRate = false;
+    }
+
     memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
     ALOGI("Initializing Qualcomm Hardware Composer");
     ALOGI("MDP version: %d", ctx->mMDP.version);
@@ -460,7 +466,7 @@
 }
 
 //Helper to roundoff the refreshrates
-static uint32_t roundOff(uint32_t refreshRate) {
+uint32_t roundOff(uint32_t refreshRate) {
     int count =  (int) (sizeof(stdRefreshRates)/sizeof(stdRefreshRates[0]));
     uint32_t rate = refreshRate;
     for(int i=0; i< count; i++) {
@@ -1052,7 +1058,7 @@
             ctx->listStats[dpy].preMultipliedAlpha = true;
 
 #ifdef DYNAMIC_FPS
-        if (dpy == HWC_DISPLAY_PRIMARY && mdpHw.isDynFpsSupported()) {
+        if (!dpy && mdpHw.isDynFpsSupported() && ctx->mUseMetaDataRefreshRate){
             //dyn fps: get refreshrate from metadata
             //Support multiple refresh rates if they are same
             //else set to  default
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 741527c..0dd25c6 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -325,6 +325,8 @@
 void getAspectRatioPosition(hwc_context_t* ctx, int dpy, int extOrientation,
                                 hwc_rect_t& inRect, hwc_rect_t& outRect);
 
+uint32_t roundOff(uint32_t refreshRate);
+
 void setRefreshRate(hwc_context_t *ctx, int dpy, uint32_t refreshRate);
 
 bool isPrimaryPortrait(hwc_context_t *ctx);
@@ -639,6 +641,8 @@
     float mAspectRatioToleranceLevel;
     // Runtime switch for BWC for targets that support it
     bool mBWCEnabled;
+    // Provides a way for OEM's to disable setting dynfps via metadata.
+    bool mUseMetaDataRefreshRate;
 };
 
 namespace qhwc {