SurfaceFlinger: Dont show Animation on External Display

- With this change the animation effect will not be shown on
  external display.
- It will change from portrait to landscape in one shot.
- Primary would still continue the animation effect
- set property sys.disable_ext_animation to disable animation

CRs-fixed: 453747

Conflicts:
	services/surfaceflinger/DisplayHardware/HWComposer.cpp
	services/surfaceflinger/DisplayHardware/HWComposer.h

Conflicts:
services/surfaceflinger/DisplayHardware/HWComposer.cpp
Change-Id: Ibd94bf166f08eeab1d504afe69230f7c6a617eb6
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 273d190..9d6199f 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -521,42 +521,50 @@
               event, disp, enabled);
         return;
     }
-    if (event != EVENT_VSYNC) {
-        ALOGW("eventControl got unexpected event %d (disp=%d en=%d)",
-              event, disp, enabled);
-        return;
-    }
     status_t err = NO_ERROR;
-    if (mHwc && !mDebugForceFakeVSync) {
-        // NOTE: we use our own internal lock here because we have to call
-        // into the HWC with the lock held, and we want to make sure
-        // that even if HWC blocks (which it shouldn't), it won't
-        // affect other threads.
-        Mutex::Autolock _l(mEventControlLock);
-        const int32_t eventBit = 1UL << event;
-        const int32_t newValue = enabled ? eventBit : 0;
-        const int32_t oldValue = mDisplayData[disp].events & eventBit;
-        if (newValue != oldValue) {
-            ATRACE_CALL();
-            err = mHwc->eventControl(mHwc, disp, event, enabled);
-            if (!err) {
-                int32_t& events(mDisplayData[disp].events);
-                events = (events & ~eventBit) | newValue;
+    switch(event) {
+        case EVENT_VSYNC:
+            if (mHwc && !mDebugForceFakeVSync) {
+                // NOTE: we use our own internal lock here because we have to
+                // call into the HWC with the lock held, and we want to make
+                // sure that even if HWC blocks (which it shouldn't), it won't
+                // affect other threads.
+                Mutex::Autolock _l(mEventControlLock);
+                const int32_t eventBit = 1UL << event;
+                const int32_t newValue = enabled ? eventBit : 0;
+                const int32_t oldValue = mDisplayData[disp].events & eventBit;
+                if (newValue != oldValue) {
+                    ATRACE_CALL();
+                    err = mHwc->eventControl(mHwc, disp, event, enabled);
+                    if (!err) {
+                        int32_t& events(mDisplayData[disp].events);
+                        events = (events & ~eventBit) | newValue;
 
-                char tag[16];
-                snprintf(tag, sizeof(tag), "HW_VSYNC_ON_%1u", disp);
-                ATRACE_INT(tag, enabled);
+                        char tag[16];
+                        snprintf(tag, sizeof(tag), "HW_VSYNC_ON_%1u", disp);
+                        ATRACE_INT(tag, enabled);
+                    }
+                }
+                // error here should not happen -- not sure what we should
+                // do if it does.
+                ALOGE_IF(err, "eventControl(%d, %d) failed %s",
+                         event, enabled, strerror(-err));
             }
-        }
-        // error here should not happen -- not sure what we should
-        // do if it does.
-        ALOGE_IF(err, "eventControl(%d, %d) failed %s",
-                event, enabled, strerror(-err));
-    }
 
-    if (err == NO_ERROR && mVSyncThread != NULL) {
-        mVSyncThread->setEnabled(enabled);
+            if (err == NO_ERROR && mVSyncThread != NULL) {
+                mVSyncThread->setEnabled(enabled);
+            }
+            break;
+        case EVENT_ORIENTATION:
+            // Orientation event
+            err = mHwc->eventControl(mHwc, disp, event, enabled);
+            break;
+        default:
+            ALOGW("eventControl got unexpected event %d (disp=%d en=%d)",
+                    event, disp, enabled);
+            break;
     }
+    return;
 }
 
 status_t HWComposer::createWorkList(int32_t id, size_t numLayers) {
@@ -689,13 +697,14 @@
             disp.hasFbComp = false;
             disp.hasOvComp = false;
             if (disp.list) {
-                for (size_t i=0 ; i<disp.list->numHwLayers ; i++) {
-                    hwc_layer_1_t& l = disp.list->hwLayers[i];
+                for (size_t j=0 ; j<disp.list->numHwLayers ; j++) {
+                    hwc_layer_1_t& l = disp.list->hwLayers[j];
 
                     //ALOGD("prepare: %d, type=%d, handle=%p",
-                    //        i, l.compositionType, l.handle);
+                    //        j, l.compositionType, l.handle);
 
-                    if (l.flags & HWC_SKIP_LAYER) {
+                    if ((i == DisplayDevice::DISPLAY_PRIMARY) &&
+                                l.flags & HWC_SKIP_LAYER) {
                         l.compositionType = HWC_FRAMEBUFFER;
                     }
                     if (l.compositionType == HWC_FRAMEBUFFER) {
@@ -1001,6 +1010,13 @@
             }
         }
     }
+    virtual void setAnimating(bool animating) {
+        if (animating) {
+            getLayer()->flags |= HWC_SCREENSHOT_ANIMATOR_LAYER;
+        } else {
+            getLayer()->flags &= ~HWC_SCREENSHOT_ANIMATOR_LAYER;
+        }
+    }
     virtual void setBlending(uint32_t blending) {
         getLayer()->blending = blending;
     }
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 79674d5..16c0f04 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -166,6 +166,7 @@
         virtual void setDefaultState() = 0;
         virtual void setSkip(bool skip) = 0;
         virtual void setIsCursorLayerHint(bool isCursor = true) = 0;
+        virtual void setAnimating(bool animating) = 0;
         virtual void setBlending(uint32_t blending) = 0;
         virtual void setTransform(uint32_t transform) = 0;
         virtual void setFrame(const Rect& frame) = 0;
@@ -249,7 +250,8 @@
     // Events handling ---------------------------------------------------------
 
     enum {
-        EVENT_VSYNC = HWC_EVENT_VSYNC
+        EVENT_VSYNC = HWC_EVENT_VSYNC,
+        EVENT_ORIENTATION = HWC_EVENT_ORIENTATION
     };
 
     void eventControl(int disp, int event, int enabled);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index f8bf368..cf9845f 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1066,6 +1066,26 @@
             sp<const DisplayDevice> hw(mDisplays[dpy]);
             const int32_t id = hw->getHwcDisplayId();
             if (id >= 0) {
+                // Get the layers in the current drawying state
+                const LayerVector& layers(mDrawingState.layersSortedByZ);
+                bool freezeSurfacePresent = false;
+                const size_t layerCount = layers.size();
+                char value[PROPERTY_VALUE_MAX];
+                property_get("sys.disable_ext_animation", value, "0");
+                if(atoi(value)) {
+                    for (size_t i = 0 ; i < layerCount ; ++i) {
+                        static int screenShotLen = strlen("ScreenshotSurface");
+                        const sp<Layer>& layer(layers[i]);
+                        if(!strncmp(layer->getName(), "ScreenshotSurface",
+                                    screenShotLen)) {
+                            // Screenshot layer is present, and animation in
+                            // progress
+                            freezeSurfacePresent = true;
+                            break;
+                        }
+                    }
+                }
+
                 const Vector< sp<Layer> >& currentLayers(
                     hw->getVisibleLayersSortedByZ());
                 const size_t count = currentLayers.size();
@@ -1078,6 +1098,26 @@
                      */
                     const sp<Layer>& layer(currentLayers[i]);
                     layer->setPerFrameData(hw, *cur);
+                    if(freezeSurfacePresent) {
+                        // if freezeSurfacePresent, set ANIMATING flag
+                        cur->setAnimating(true);
+                    } else {
+                        const KeyedVector<wp<IBinder>, DisplayDeviceState>&
+                                                draw(mDrawingState.displays);
+                        size_t dc = draw.size();
+                        for (size_t i=0 ; i<dc ; i++) {
+                            if (draw[i].isMainDisplay()) {
+                                HWComposer& hwc(getHwComposer());
+                                if (hwc.initCheck() == NO_ERROR)
+                                    // Pass the current orientation to HWC
+                                    // which will be used to block animation
+                                    // on external
+                                    hwc.eventControl(HWC_DISPLAY_PRIMARY,
+                                            SurfaceFlinger::EVENT_ORIENTATION,
+                                            uint32_t(draw[i].orientation));
+                            }
+                        }
+                    }
                 }
             }
         }
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 2790ac1..53b616c 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -98,7 +98,8 @@
     void run() ANDROID_API;
 
     enum {
-        EVENT_VSYNC = HWC_EVENT_VSYNC
+        EVENT_VSYNC = HWC_EVENT_VSYNC,
+        EVENT_ORIENTATION = HWC_EVENT_ORIENTATION
     };
 
     // post an asynchronous message to the main thread