Merge "Fix typo in ProtoLogViewerConfigReader.java" into main
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
index 4c7d90c..d538f52 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
@@ -449,7 +449,7 @@
                 }
 
                 // We need to reset the View state, even if the animation was cancelled
-                onAppearAnimationFinished(isAppearing);
+                onAppearAnimationFinished(isAppearing, /* cancelled = */ !mRunWithoutInterruptions);
 
                 if (mRunWithoutInterruptions) {
                     InteractionJankMonitor.getInstance().end(getCujType(isAppearing));
@@ -463,6 +463,7 @@
                 if (onStartedRunnable != null) {
                     onStartedRunnable.run();
                 }
+                onAppearAnimationStarted(isAppearing);
                 mRunWithoutInterruptions = true;
                 Configuration.Builder builder = Configuration.Builder
                         .withView(getCujType(isAppearing), ActivatableNotificationView.this);
@@ -486,6 +487,8 @@
                 frameTimeNanos -> {
                     if (mAppearAnimator == cachedAnimator) {
                         mAppearAnimator.start();
+                    } else {
+                        onAppearAnimationSkipped(isAppearing);
                     }
                 }, delay);
     }
@@ -502,7 +505,13 @@
         }
     }
 
-    protected void onAppearAnimationFinished(boolean wasAppearing) {
+    protected void onAppearAnimationStarted(boolean isAppear) {
+    }
+
+    protected void onAppearAnimationSkipped(boolean isAppear) {
+    }
+
+    protected void onAppearAnimationFinished(boolean wasAppearing, boolean cancelled) {
     }
 
     private void cancelAppearAnimation() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index 33dbbc2..38e6609 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -1835,6 +1835,25 @@
         void logSkipResetAllContentAlphas(
                 NotificationEntry entry
         );
+
+        /** Called when we start an appear animation. */
+        void logStartAppearAnimation(NotificationEntry entry, boolean isAppear);
+
+        /** Called when we cancel the running appear animation. */
+        void logCancelAppearDrawing(NotificationEntry entry, boolean wasDrawing);
+
+        /** Called when the animator of the appear animation is started. */
+        void logAppearAnimationStarted(NotificationEntry entry, boolean isAppear);
+
+        /** Called when we prepared an appear animation, but the animator was never started. */
+        void logAppearAnimationSkipped(NotificationEntry entry, boolean isAppear);
+
+        /** Called when the animator of the appear animation is finished. */
+        void logAppearAnimationFinished(
+                NotificationEntry entry,
+                boolean isAppear,
+                boolean cancelled
+        );
     }
 
     /**
@@ -3165,6 +3184,13 @@
     }
 
     @Override
+    public void performAddAnimation(long delay, long duration, boolean isHeadsUpAppear,
+            Runnable onFinishRunnable) {
+        mLogger.logStartAppearAnimation(getEntry(), /* isAppear = */ true);
+        super.performAddAnimation(delay, duration, isHeadsUpAppear, onFinishRunnable);
+    }
+
+    @Override
     public long performRemoveAnimation(
             long duration,
             long delay,
@@ -3173,6 +3199,7 @@
             Runnable onStartedRunnable,
             Runnable onFinishedRunnable,
             AnimatorListenerAdapter animationListener, ClipSide clipSide) {
+        mLogger.logStartAppearAnimation(getEntry(), /* isAppear = */ false);
         if (mMenuRow != null && mMenuRow.isMenuVisible()) {
             Animator anim = getTranslateViewAnimator(0f, null /* listener */);
             if (anim != null) {
@@ -3201,8 +3228,25 @@
     }
 
     @Override
-    protected void onAppearAnimationFinished(boolean wasAppearing) {
-        super.onAppearAnimationFinished(wasAppearing);
+    protected void onAppearAnimationStarted(boolean isAppear) {
+        mLogger.logAppearAnimationStarted(getEntry(), /* isAppear = */ isAppear);
+        super.onAppearAnimationStarted(isAppear);
+    }
+
+    @Override
+    protected void onAppearAnimationSkipped(boolean isAppear) {
+        mLogger.logAppearAnimationSkipped(getEntry(),  /* isAppear = */ isAppear);
+        super.onAppearAnimationSkipped(isAppear);
+    }
+
+    @Override
+    protected void onAppearAnimationFinished(boolean wasAppearing, boolean cancelled) {
+        mLogger.logAppearAnimationFinished(
+                /* entry = */ getEntry(),
+                /* isAppear = */ wasAppearing,
+                /* cancelled = */ cancelled
+        );
+        super.onAppearAnimationFinished(wasAppearing, cancelled);
         if (wasAppearing) {
             // During the animation the visible view might have changed, so let's make sure all
             // alphas are reset
@@ -3218,6 +3262,12 @@
     }
 
     @Override
+    public void cancelAppearDrawing() {
+        mLogger.logCancelAppearDrawing(getEntry(), isDrawingAppearAnimation());
+        super.cancelAppearDrawing();
+    }
+
+    @Override
     public void resetAllContentAlphas() {
         mLogger.logResetAllContentAlphas(getEntry());
         mPrivateLayout.setAlpha(1f);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
index c31a2cb..23a2fac 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
@@ -209,6 +209,32 @@
                 ) {
                     mLogBufferLogger.logSkipResetAllContentAlphas(entry);
                 }
+
+                @Override
+                public void logStartAppearAnimation(NotificationEntry entry, boolean isAppear) {
+                    mLogBufferLogger.logStartAppearAnimation(entry, isAppear);
+                }
+
+                @Override
+                public void logCancelAppearDrawing(NotificationEntry entry, boolean wasDrawing) {
+                    mLogBufferLogger.logCancelAppearDrawing(entry, wasDrawing);
+                }
+
+                @Override
+                public void logAppearAnimationStarted(NotificationEntry entry, boolean isAppear) {
+                    mLogBufferLogger.logAppearAnimationStarted(entry, isAppear);
+                }
+
+                @Override
+                public void logAppearAnimationSkipped(NotificationEntry entry, boolean isAppear) {
+                    mLogBufferLogger.logAppearAnimationSkipped(entry, isAppear);
+                }
+
+                @Override
+                public void logAppearAnimationFinished(NotificationEntry entry, boolean isAppear,
+                        boolean cancelled) {
+                    mLogBufferLogger.logAppearAnimationFinished(entry, isAppear, cancelled);
+                }
             };
 
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowLogger.kt
index b1e9032..6e78f56 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowLogger.kt
@@ -30,7 +30,7 @@
 @Inject
 constructor(
     @NotificationLog private val buffer: LogBuffer,
-    @NotificationRenderLog private val notificationRenderBuffer: LogBuffer
+    @NotificationRenderLog private val notificationRenderBuffer: LogBuffer,
 ) {
     fun logKeepInParentChildDetached(child: NotificationEntry, oldParent: NotificationEntry?) {
         buffer.log(
@@ -40,7 +40,7 @@
                 str1 = child.logKey
                 str2 = oldParent.logKey
             },
-            { "Detach child $str1 kept in parent $str2" }
+            { "Detach child $str1 kept in parent $str2" },
         )
     }
 
@@ -52,13 +52,13 @@
                 str1 = child.logKey
                 str2 = newParent.logKey
             },
-            { "Skipping to attach $str1 to $str2, because it still flagged to keep in parent" }
+            { "Skipping to attach $str1 to $str2, because it still flagged to keep in parent" },
         )
     }
 
     fun logRemoveTransientFromContainer(
         childEntry: NotificationEntry,
-        containerEntry: NotificationEntry
+        containerEntry: NotificationEntry,
     ) {
         notificationRenderBuffer.log(
             TAG,
@@ -67,25 +67,20 @@
                 str1 = childEntry.logKey
                 str2 = containerEntry.logKey
             },
-            { "RemoveTransientRow from ChildrenContainer: childKey: $str1 -- containerKey: $str2" }
+            { "RemoveTransientRow from ChildrenContainer: childKey: $str1 -- containerKey: $str2" },
         )
     }
 
-    fun logRemoveTransientFromNssl(
-        childEntry: NotificationEntry,
-    ) {
+    fun logRemoveTransientFromNssl(childEntry: NotificationEntry) {
         notificationRenderBuffer.log(
             TAG,
             LogLevel.INFO,
             { str1 = childEntry.logKey },
-            { "RemoveTransientRow from Nssl: childKey: $str1" }
+            { "RemoveTransientRow from Nssl: childKey: $str1" },
         )
     }
 
-    fun logRemoveTransientFromViewGroup(
-        childEntry: NotificationEntry,
-        containerView: ViewGroup,
-    ) {
+    fun logRemoveTransientFromViewGroup(childEntry: NotificationEntry, containerView: ViewGroup) {
         notificationRenderBuffer.log(
             TAG,
             LogLevel.WARNING,
@@ -93,14 +88,14 @@
                 str1 = childEntry.logKey
                 str2 = containerView.toString()
             },
-            { "RemoveTransientRow from other ViewGroup: childKey: $str1 -- ViewGroup: $str2" }
+            { "RemoveTransientRow from other ViewGroup: childKey: $str1 -- ViewGroup: $str2" },
         )
     }
 
     fun logAddTransientRow(
         childEntry: NotificationEntry,
         containerEntry: NotificationEntry,
-        index: Int
+        index: Int,
     ) {
         notificationRenderBuffer.log(
             TAG,
@@ -110,14 +105,11 @@
                 str2 = containerEntry.logKey
                 int1 = index
             },
-            { "addTransientRow to row: childKey: $str1 -- containerKey: $str2 -- index: $int1" }
+            { "addTransientRow to row: childKey: $str1 -- containerKey: $str2 -- index: $int1" },
         )
     }
 
-    fun logRemoveTransientRow(
-        childEntry: NotificationEntry,
-        containerEntry: NotificationEntry,
-    ) {
+    fun logRemoveTransientRow(childEntry: NotificationEntry, containerEntry: NotificationEntry) {
         notificationRenderBuffer.log(
             TAG,
             LogLevel.ERROR,
@@ -125,7 +117,7 @@
                 str1 = childEntry.logKey
                 str2 = containerEntry.logKey
             },
-            { "removeTransientRow from row: childKey: $str1 -- containerKey: $str2" }
+            { "removeTransientRow from row: childKey: $str1 -- containerKey: $str2" },
         )
     }
 
@@ -134,7 +126,7 @@
             TAG,
             LogLevel.INFO,
             { str1 = entry.logKey },
-            { "resetAllContentAlphas: $str1" }
+            { "resetAllContentAlphas: $str1" },
         )
     }
 
@@ -143,7 +135,72 @@
             TAG,
             LogLevel.INFO,
             { str1 = entry.logKey },
-            { "Skip resetAllContentAlphas: $str1" }
+            { "Skip resetAllContentAlphas: $str1" },
+        )
+    }
+
+    fun logStartAppearAnimation(entry: NotificationEntry, isAppear: Boolean) {
+        notificationRenderBuffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            {
+                str1 = entry.logKey
+                bool1 = isAppear
+            },
+            { "startAppearAnimation childKey: $str1 isAppear:$bool1" },
+        )
+    }
+
+    fun logCancelAppearDrawing(entry: NotificationEntry, wasDrawing: Boolean) {
+        notificationRenderBuffer.log(
+            TAG,
+            LogLevel.WARNING,
+            {
+                str1 = entry.logKey
+                bool1 = wasDrawing
+            },
+            { "cancelAppearDrawing childKey: $str1 wasDrawing:$bool1" },
+        )
+    }
+
+    fun logAppearAnimationStarted(entry: NotificationEntry, isAppear: Boolean) {
+        notificationRenderBuffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            {
+                str1 = entry.logKey
+                bool1 = isAppear
+            },
+            { "onAppearAnimationStarted childKey: $str1 isAppear:$bool1" },
+        )
+    }
+
+    fun logAppearAnimationSkipped(entry: NotificationEntry, isAppear: Boolean) {
+        notificationRenderBuffer.log(
+            TAG,
+            LogLevel.WARNING,
+            {
+                str1 = entry.logKey
+                bool1 = isAppear
+            },
+            { "Skipped an appear animation childKey: $str1 isAppear:$bool1" },
+        )
+    }
+
+    fun logAppearAnimationFinished(
+        entry: NotificationEntry,
+        isAppear: Boolean,
+        cancelled: Boolean,
+    ) {
+        notificationRenderBuffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            {
+                str1 = entry.logKey
+                bool1 = isAppear
+                bool2 = cancelled
+            },
+            { "onAppearAnimationFinished childKey: $str1 isAppear:$bool1 cancelled:$bool2" },
         )
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
index ed7383c..e3e2491 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
@@ -612,6 +612,8 @@
         Assert.assertNull(child.getParent());
         Assert.assertNull(child.getNotificationParent());
         Assert.assertFalse(child.keepInParentForDismissAnimation());
+        verify(mNotificationTestHelper.getMockLogger())
+                .logCancelAppearDrawing(child.getEntry(), false);
         verifyNoMoreInteractions(mNotificationTestHelper.getMockLogger());
     }
 
@@ -1013,7 +1015,7 @@
         assertThat(row.isHeadsUpAnimatingAway()).isTrue();
 
         // on disappear animation ends
-        row.onAppearAnimationFinished(/* wasAppearing = */ false);
+        row.onAppearAnimationFinished(/* wasAppearing = */ false, /* cancelled = */ false);
         assertThat(row.isHeadsUpAnimatingAway()).isFalse();
     }