hwc: Program default mode upon boot anim completion

Default display mode needs to applied exactly on boot
completion. Hence we check for the exact instance of
boot completion by checking the property of boot
animation exit. We keep on checking till the property
is found to be set and program the default mode over
a dynamic link to libmm-qdcm.so

Change-Id: Ic68667a12e4058f29bc2203382baf59ef34ab038
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index fd3bb69..8a80140 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -255,6 +255,8 @@
     hwc_context_t* ctx = (hwc_context_t*)(dev);
     const int dpy = HWC_DISPLAY_PRIMARY;
     bool fbComp = false;
+    if (!ctx->mBootAnimCompleted)
+        processBootAnimCompleted(ctx);
     if (LIKELY(list && list->numHwLayers > 1) && ctx->dpyAttr[dpy].connected &&
             (ctx->dpyAttr[dpy].isActive ||
              ctx->mHDMIDisplay->isHDMIPrimaryDisplay())
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 8139013..931a876 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -44,6 +44,7 @@
 #include "hwc_virtual.h"
 #include "qd_utils.h"
 #include <sys/sysinfo.h>
+#include <dlfcn.h>
 
 using namespace qClient;
 using namespace qService;
@@ -389,6 +390,9 @@
     property_get("debug.sf.hwc.canUseABC", value, "0");
     ctx->enableABC  = atoi(value) ? true : false;
 
+    // Initializing boot anim completed check to false
+    ctx->mBootAnimCompleted = false;
+
     // Initialize gpu perfomance hint related parameters
     property_get("sys.hwc.gpu_perf_mode", value, "0");
 #ifdef QCOM_BSP
@@ -2492,6 +2496,36 @@
     return (eqBounds == 3);
 }
 
+void processBootAnimCompleted(hwc_context_t *ctx) {
+    char value[PROPERTY_VALUE_MAX];
+    int boot_finished = 0, ret = -1;
+    int (*applyMode)(int) = NULL;
+    void *modeHandle = NULL;
+
+    // Reading property set on boot finish in SF
+    property_get("service.bootanim.exit", value, "0");
+    boot_finished = atoi(value);
+    if (!boot_finished)
+        return;
+
+    modeHandle = dlopen("libmm-qdcm.so", RTLD_NOW);
+    if (modeHandle) {
+        *(void **)&applyMode = dlsym(modeHandle, "applyDefaults");
+        if (applyMode) {
+            ret = applyMode(HWC_DISPLAY_PRIMARY);
+            if (ret)
+                ALOGD("%s: Not able to apply default mode", __FUNCTION__);
+        } else {
+            ALOGE("%s: No symbol applyDefaults found", __FUNCTION__);
+        }
+        dlclose(modeHandle);
+    } else {
+        ALOGE("%s: Not able to load libmm-qdcm.so", __FUNCTION__);
+    }
+
+    ctx->mBootAnimCompleted = true;
+}
+
 void BwcPM::setBwc(const hwc_context_t *ctx, const int& dpy,
         const private_handle_t *hnd,
         const hwc_rect_t& crop, const hwc_rect_t& dst,
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 797f9b0..e5110c1 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -439,6 +439,9 @@
 // Returns true if rect1 is peripheral to rect2, false otherwise.
 bool isPeripheral(const hwc_rect_t& rect1, const hwc_rect_t& rect2);
 
+// Checks if boot animation has completed and applies default mode
+void processBootAnimCompleted(hwc_context_t *ctx);
+
 // Inline utility functions
 static inline bool isSkipLayer(const hwc_layer_1_t* l) {
     return (UNLIKELY(l && (l->flags & HWC_SKIP_LAYER)));
@@ -641,6 +644,8 @@
     bool mUseMetaDataRefreshRate;
    // Stores the hpd enabled status- avoids re-enabling HDP on suspend resume.
     bool mHPDEnabled;
+    //Used to notify that boot has completed
+    bool mBootAnimCompleted;
 };
 
 namespace qhwc {