WM: Replace eEarlyWakeup flags with explicit eEarlyWakeup start and end flags

eEarlyWakeup flag is used as a hint to SurfaceFlinger to adjust its
offsets so it can wakeup earlier and have sufficient time to compose
more complex scenes.

This flag has been replaced with explicit start and stop flags which
ensure the SurfaceFlinger offsets remain consistent during animation.

Bug: 158127834
Test: go/wm-smoke
Test: systrace to verify new tracepoint and offset behavior

Change-Id: Ib9c35c01a6bf02f88ec7cb1778e01909bd2f9055
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 6f73e89..eda2cea 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -102,6 +102,8 @@
             long otherTransactionObj);
     private static native void nativeSetAnimationTransaction(long transactionObj);
     private static native void nativeSetEarlyWakeup(long transactionObj);
+    private static native void nativeSetEarlyWakeupStart(long transactionObj);
+    private static native void nativeSetEarlyWakeupEnd(long transactionObj);
 
     private static native void nativeSetLayer(long transactionObj, long nativeObject, int zorder);
     private static native void nativeSetRelativeLayer(long transactionObj, long nativeObject,
@@ -2797,6 +2799,8 @@
         }
 
         /**
+         * @deprecated use {@link Transaction#setEarlyWakeupStart()}
+         *
          * Indicate that SurfaceFlinger should wake up earlier than usual as a result of this
          * transaction. This should be used when the caller thinks that the scene is complex enough
          * that it's likely to hit GL composition, and thus, SurfaceFlinger needs to more time in
@@ -2805,11 +2809,35 @@
          * Corresponds to setting ISurfaceComposer::eEarlyWakeup
          * @hide
          */
+        @Deprecated
         public Transaction setEarlyWakeup() {
             nativeSetEarlyWakeup(mNativeObject);
             return this;
         }
 
+         /**
+          * Provides a hint to SurfaceFlinger to change its offset so that SurfaceFlinger wakes up
+          * earlier to compose surfaces. The caller should use this as a hint to SurfaceFlinger
+          * when the scene is complex enough to use GPU composition. The hint will remain active
+          * until until the client calls {@link Transaction#setEarlyWakeupEnd}.
+          *
+          * @hide
+          */
+        public Transaction setEarlyWakeupStart() {
+            nativeSetEarlyWakeupStart(mNativeObject);
+            return this;
+        }
+
+        /**
+         * Removes the early wake up hint set by {@link Transaction#setEarlyWakeupStart}.
+         *
+         * @hide
+         */
+        public Transaction setEarlyWakeupEnd() {
+            nativeSetEarlyWakeupEnd(mNativeObject);
+            return this;
+        }
+
         /**
          * Sets an arbitrary piece of metadata on the surface. This is a helper for int data.
          * @hide
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index c098fae..a0a9842 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -640,7 +640,7 @@
                 mTmpRect.set(0, 0, mSurfaceWidth, mSurfaceHeight);
             }
             SyncRtSurfaceTransactionApplier applier = new SyncRtSurfaceTransactionApplier(this);
-            applier.scheduleApply(false /* earlyWakeup */,
+            applier.scheduleApply(
                     new SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(mSurfaceControl)
                             .withWindowCrop(mTmpRect)
                             .build());
diff --git a/core/java/android/view/SyncRtSurfaceTransactionApplier.java b/core/java/android/view/SyncRtSurfaceTransactionApplier.java
index 9c97f3e..062285f 100644
--- a/core/java/android/view/SyncRtSurfaceTransactionApplier.java
+++ b/core/java/android/view/SyncRtSurfaceTransactionApplier.java
@@ -53,11 +53,10 @@
     /**
      * Schedules applying surface parameters on the next frame.
      *
-     * @param earlyWakeup Whether to set {@link Transaction#setEarlyWakeup()} on transaction.
      * @param params The surface parameters to apply. DO NOT MODIFY the list after passing into
      *               this method to avoid synchronization issues.
      */
-    public void scheduleApply(boolean earlyWakeup, final SurfaceParams... params) {
+    public void scheduleApply(final SurfaceParams... params) {
         if (mTargetViewRootImpl == null) {
             return;
         }
@@ -67,7 +66,7 @@
                 return;
             }
             Transaction t = new Transaction();
-            applyParams(t, frame, earlyWakeup, params);
+            applyParams(t, frame, params);
         });
 
         // Make sure a frame gets scheduled.
@@ -78,12 +77,10 @@
      * Applies surface parameters on the next frame.
      * @param t transaction to apply all parameters in.
      * @param frame frame to synchronize to. Set -1 when sync is not required.
-     * @param earlyWakeup Whether to set {@link Transaction#setEarlyWakeup()} on transaction.
      * @param params The surface parameters to apply. DO NOT MODIFY the list after passing into
      *               this method to avoid synchronization issues.
      */
-     void applyParams(Transaction t, long frame, boolean earlyWakeup,
-            final SurfaceParams... params) {
+     void applyParams(Transaction t, long frame, final SurfaceParams... params) {
         for (int i = params.length - 1; i >= 0; i--) {
             SurfaceParams surfaceParams = params[i];
             SurfaceControl surface = surfaceParams.surface;
@@ -92,9 +89,6 @@
             }
             applyParams(t, surfaceParams, mTmpFloat9);
         }
-        if (earlyWakeup) {
-            t.setEarlyWakeup();
-        }
         t.apply();
     }
 
diff --git a/core/java/android/view/ViewRootInsetsControllerHost.java b/core/java/android/view/ViewRootInsetsControllerHost.java
index 686d561..31a4402 100644
--- a/core/java/android/view/ViewRootInsetsControllerHost.java
+++ b/core/java/android/view/ViewRootInsetsControllerHost.java
@@ -120,13 +120,12 @@
             mApplier = new SyncRtSurfaceTransactionApplier(mViewRoot.mView);
         }
         if (mViewRoot.mView.isHardwareAccelerated()) {
-            mApplier.scheduleApply(false /* earlyWakeup */, params);
+            mApplier.scheduleApply(params);
         } else {
             // Window doesn't support hardware acceleration, no synchronization for now.
             // TODO(b/149342281): use mViewRoot.mSurface.getNextFrameNumber() to sync on every
             //  frame instead.
-            mApplier.applyParams(new SurfaceControl.Transaction(), -1 /* frame */,
-                    false /* earlyWakeup */, params);
+            mApplier.applyParams(new SurfaceControl.Transaction(), -1 /* frame */, params);
         }
     }
 
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index e553a78..ae36f8a 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -395,6 +395,16 @@
     transaction->setEarlyWakeup();
 }
 
+static void nativeSetEarlyWakeupStart(JNIEnv* env, jclass clazz, jlong transactionObj) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+    transaction->setExplicitEarlyWakeupStart();
+}
+
+static void nativeSetEarlyWakeupEnd(JNIEnv* env, jclass clazz, jlong transactionObj) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+    transaction->setExplicitEarlyWakeupEnd();
+}
+
 static void nativeSetLayer(JNIEnv* env, jclass clazz, jlong transactionObj,
         jlong nativeObject, jint zorder) {
     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
@@ -1501,6 +1511,10 @@
             (void*)nativeSetAnimationTransaction },
     {"nativeSetEarlyWakeup", "(J)V",
             (void*)nativeSetEarlyWakeup },
+    {"nativeSetEarlyWakeupStart", "(J)V",
+            (void*)nativeSetEarlyWakeupStart },
+    {"nativeSetEarlyWakeupEnd", "(J)V",
+            (void*)nativeSetEarlyWakeupEnd },
     {"nativeSetLayer", "(JJI)V",
             (void*)nativeSetLayer },
     {"nativeSetRelativeLayer", "(JJJI)V",
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java
index 31fe22e..82e6251 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java
@@ -115,7 +115,6 @@
                     t.deferTransactionUntil(surfaceParams.surface, mBarrierSurfaceControl, frame);
                     surfaceParams.applyTo(t);
                 }
-                t.setEarlyWakeup();
                 t.apply();
                 Trace.traceEnd(Trace.TRACE_TAG_VIEW);
                 Message.obtain(mApplyHandler, MSG_UPDATE_SEQUENCE_NUMBER, toApplySeqNo, 0)
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java
index bdb6c06..b966f93 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java
@@ -99,8 +99,8 @@
         return this;
     }
 
+    @Deprecated
     public TransactionCompat setEarlyWakeup() {
-        mTransaction.setEarlyWakeup();
         return this;
     }
 
@@ -114,7 +114,7 @@
         t.deferTransactionUntil(surfaceControl, barrier, frameNumber);
     }
 
+    @Deprecated
     public static void setEarlyWakeup(Transaction t) {
-        t.setEarlyWakeup();
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
index 6a33024..382715a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
@@ -293,7 +293,7 @@
                     .withCornerRadius(mCornerRadius)
                     .withVisibility(true)
                     .build();
-            mSyncRtTransactionApplier.scheduleApply(true /* earlyWakeup */, params);
+            mSyncRtTransactionApplier.scheduleApply(params);
         }
 
         @Override
diff --git a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java
index 5633b6b..837f1b5 100644
--- a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java
+++ b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java
@@ -239,9 +239,6 @@
     }
 
     private void applyTransformation(RunningAnimation a, Transaction t, long currentPlayTime) {
-        if (a.mAnimSpec.needsEarlyWakeup()) {
-            t.setEarlyWakeup();
-        }
         a.mAnimSpec.apply(t, a.mLeash, currentPlayTime);
     }
 
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index 92a9e30..9d0bac9 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -17,6 +17,10 @@
 package com.android.server.wm;
 
 import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS;
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_ALL;
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS;
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_SCREEN_ROTATION;
 import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN;
 import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
@@ -52,6 +56,9 @@
     /** Is any window animating? */
     private boolean mLastRootAnimating;
 
+    /** True if we are running any animations that require expensive composition. */
+    private boolean mRunningExpensiveAnimations;
+
     final Choreographer.FrameCallback mAnimationFrameCallback;
 
     /** Time of current animation step. Reset on each iteration */
@@ -165,12 +172,8 @@
                 mService.mWatermark.drawIfNeeded();
             }
 
-            SurfaceControl.mergeToGlobalTransaction(mTransaction);
         } catch (RuntimeException e) {
             Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
-        } finally {
-            mService.closeSurfaceTransaction("WindowAnimator");
-            ProtoLog.i(WM_SHOW_TRANSACTIONS, "<<< CLOSE TRANSACTION animate");
         }
 
         final boolean hasPendingLayoutChanges = mService.mRoot.hasPendingLayoutChanges(this);
@@ -179,21 +182,36 @@
             mService.mWindowPlacerLocked.requestTraversal();
         }
 
-        final boolean rootAnimating = mService.mRoot.isAnimating(TRANSITION | CHILDREN);
+        final boolean rootAnimating = mService.mRoot.isAnimating(TRANSITION | CHILDREN /* flags */,
+                ANIMATION_TYPE_ALL /* typesToCheck */);
         if (rootAnimating && !mLastRootAnimating) {
-            // Usually app transitions but quite a load onto the system already (with all the things
-            // happening in app), so pause task snapshot persisting to not increase the load.
-            mService.mTaskSnapshotController.setPersisterPaused(true);
             Trace.asyncTraceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "animating", 0);
         }
         if (!rootAnimating && mLastRootAnimating) {
             mService.mWindowPlacerLocked.requestTraversal();
-            mService.mTaskSnapshotController.setPersisterPaused(false);
             Trace.asyncTraceEnd(Trace.TRACE_TAG_WINDOW_MANAGER, "animating", 0);
         }
-
         mLastRootAnimating = rootAnimating;
 
+        final boolean runningExpensiveAnimations =
+                mService.mRoot.isAnimating(TRANSITION | CHILDREN /* flags */,
+                        ANIMATION_TYPE_APP_TRANSITION | ANIMATION_TYPE_SCREEN_ROTATION
+                                | ANIMATION_TYPE_RECENTS /* typesToCheck */);
+        if (runningExpensiveAnimations && !mRunningExpensiveAnimations) {
+            // Usually app transitions put quite a load onto the system already (with all the things
+            // happening in app), so pause task snapshot persisting to not increase the load.
+            mService.mTaskSnapshotController.setPersisterPaused(true);
+            mTransaction.setEarlyWakeupStart();
+        } else if (!runningExpensiveAnimations && mRunningExpensiveAnimations) {
+            mService.mTaskSnapshotController.setPersisterPaused(false);
+            mTransaction.setEarlyWakeupEnd();
+        }
+        mRunningExpensiveAnimations = runningExpensiveAnimations;
+
+        SurfaceControl.mergeToGlobalTransaction(mTransaction);
+        mService.closeSurfaceTransaction("WindowAnimator");
+        ProtoLog.i(WM_SHOW_TRANSACTIONS, "<<< CLOSE TRANSACTION animate");
+
         if (mRemoveReplacedWindows) {
             mService.mRoot.removeReplacedWindows();
             mRemoveReplacedWindows = false;