liboverlay: close all the opened pipes after framework reboot.

b/7147557

Add initOverlay() function to close all the opened pipes when
Surfaceflinger process gets killed.

Change-Id: I9c65a61c81f9c81198f1076d6cbd27933b164c05
Signed-off-by: Iliyan Malchev <malchev@google.com>
diff --git a/liboverlay/overlay.cpp b/liboverlay/overlay.cpp
index 3fdb7c4..37e99df 100644
--- a/liboverlay/overlay.cpp
+++ b/liboverlay/overlay.cpp
@@ -190,8 +190,12 @@
 Overlay *Overlay::sInstance = 0;
 
 Overlay* Overlay::getInstance() {
-    if(sInstance == NULL)
+    if(sInstance == NULL) {
+        if(utils::initOverlay() == -1) {
+            ALOGE("utils::initOverlay() ERROR!!");
+        }
         sInstance = new Overlay();
+    }
     return sInstance;
 }
 
diff --git a/liboverlay/overlayUtils.cpp b/liboverlay/overlayUtils.cpp
index 4956f90..1c9c72b 100644
--- a/liboverlay/overlayUtils.cpp
+++ b/liboverlay/overlayUtils.cpp
@@ -84,6 +84,10 @@
 
 
 namespace utils {
+//------------------ defines -----------------------------
+#define FB_DEVICE_TEMPLATE "/dev/graphics/fb%u"
+#define NUM_FB_DEVICES 3
+
 //--------------------------------------------------------
 FrameBufferInfo::FrameBufferInfo() {
     mFBWidth = 0;
@@ -154,6 +158,50 @@
     return (trueMirroringSupported && mBorderFillSupported);
 }
 
+/* clears any VG pipes allocated to the fb devices */
+int initOverlay() {
+    msmfb_mixer_info_req  req;
+    mdp_mixer_info *minfo = NULL;
+    char name[64];
+    int fd = -1;
+    for(int i = 0; i < NUM_FB_DEVICES; i++) {
+        snprintf(name, 64, FB_DEVICE_TEMPLATE, i);
+        ALOGD("initoverlay:: opening the device:: %s", name);
+        fd = ::open(name, O_RDWR, 0);
+        if(fd < 0) {
+            ALOGE("cannot open framebuffer(%d)", i);
+            return -1;
+        }
+        //Get the mixer configuration */
+        req.mixer_num = i;
+        if (ioctl(fd, MSMFB_MIXER_INFO, &req) == -1) {
+            ALOGE("ERROR: MSMFB_MIXER_INFO ioctl failed");
+            close(fd);
+            return -1;
+        }
+        minfo = req.info;
+        for (int j = 0; j < req.cnt; j++) {
+            ALOGD("ndx=%d num=%d z_order=%d", minfo->pndx, minfo->pnum,
+                    minfo->z_order);
+            // except the RGB base layer with z_order of -1, clear any
+            // other pipes connected to mixer.
+            if((minfo->z_order) != -1) {
+                int index = minfo->pndx;
+                ALOGD("Unset overlay with index: %d at mixer %d", index, i);
+                if(ioctl(fd, MSMFB_OVERLAY_UNSET, &index) == -1) {
+                    ALOGE("ERROR: MSMFB_OVERLAY_UNSET failed");
+                    close(fd);
+                    return -1;
+                }
+            }
+            minfo++;
+        }
+        close(fd);
+        fd = -1;
+    }
+    return 0;
+}
+
 //--------------------------------------------------------
 //Refer to graphics.h, gralloc_priv.h, msm_mdp.h
 int getMdpFormat(int format) {
diff --git a/liboverlay/overlayUtils.h b/liboverlay/overlayUtils.h
index fdaa22a..e5f7119 100644
--- a/liboverlay/overlayUtils.h
+++ b/liboverlay/overlayUtils.h
@@ -145,6 +145,11 @@
 enum { BARRIER_LAND = 1,
     BARRIER_PORT = 2 };
 
+/* if SurfaceFlinger process gets killed in bypass mode, In initOverlay()
+ * close all the pipes if it is opened after reboot.
+ */
+int initOverlay(void);
+
 inline uint32_t format3D(uint32_t x) { return x & 0xFF000; }
 inline uint32_t colorFormat(uint32_t fmt) {
     /*TODO enable this block only if format has interlace / 3D info in top bits.