Add reset PULSING roundness on NotificationEntry removed

Test: atest HeadsUpAppearanceControllerTest
Test: manual test
Bug: 261963279
Change-Id: I617b06f9e4c05b2bfbccf1e77d0c7eaf12106b91
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
index c217ab3..69f7c71 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
@@ -22,6 +22,8 @@
 import android.util.MathUtils;
 import android.view.View;
 
+import androidx.annotation.NonNull;
+
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.widget.ViewClippingUtil;
 import com.android.systemui.R;
@@ -197,6 +199,11 @@
         updateHeadsUpAndPulsingRoundness(entry);
     }
 
+    @Override
+    public void onHeadsUpStateChanged(@NonNull NotificationEntry entry, boolean isHeadsUp) {
+        updateHeadsUpAndPulsingRoundness(entry);
+    }
+
     private void updateTopEntry() {
         NotificationEntry newEntry = null;
         if (shouldBeVisible()) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
index 9727b6c5..e5e5d94 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.statusbar.phone;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.isNull;
 import static org.mockito.Mockito.mock;
@@ -33,12 +35,14 @@
 
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.flags.Flags;
 import com.android.systemui.plugins.DarkIconDispatcher;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.shade.NotificationPanelViewController;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.HeadsUpStatusBarView;
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
 import com.android.systemui.statusbar.notification.stack.NotificationRoundnessManager;
@@ -64,7 +68,9 @@
             mock(NotificationPanelViewController.class);
     private final DarkIconDispatcher mDarkIconDispatcher = mock(DarkIconDispatcher.class);
     private HeadsUpAppearanceController mHeadsUpAppearanceController;
-    private ExpandableNotificationRow mFirst;
+    private NotificationTestHelper mTestHelper;
+    private ExpandableNotificationRow mRow;
+    private NotificationEntry mEntry;
     private HeadsUpStatusBarView mHeadsUpStatusBarView;
     private HeadsUpManagerPhone mHeadsUpManager;
     private View mOperatorNameView;
@@ -79,11 +85,12 @@
     @Before
     public void setUp() throws Exception {
         allowTestableLooperAsMainThread();
-        NotificationTestHelper testHelper = new NotificationTestHelper(
+        mTestHelper = new NotificationTestHelper(
                 mContext,
                 mDependency,
                 TestableLooper.get(this));
-        mFirst = testHelper.createRow();
+        mRow = mTestHelper.createRow();
+        mEntry = mRow.getEntry();
         mHeadsUpStatusBarView = new HeadsUpStatusBarView(mContext, mock(View.class),
                 mock(TextView.class));
         mHeadsUpManager = mock(HeadsUpManagerPhone.class);
@@ -95,6 +102,7 @@
         mCommandQueue = mock(CommandQueue.class);
         mNotificationRoundnessManager = mock(NotificationRoundnessManager.class);
         mFeatureFlag = mock(FeatureFlags.class);
+        when(mFeatureFlag.isEnabled(Flags.USE_ROUNDNESS_SOURCETYPES)).thenReturn(true);
         mHeadsUpAppearanceController = new HeadsUpAppearanceController(
                 mock(NotificationIconAreaController.class),
                 mHeadsUpManager,
@@ -116,60 +124,60 @@
 
     @Test
     public void testShowinEntryUpdated() {
-        mFirst.setPinned(true);
+        mRow.setPinned(true);
         when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(true);
-        when(mHeadsUpManager.getTopEntry()).thenReturn(mFirst.getEntry());
-        mHeadsUpAppearanceController.onHeadsUpPinned(mFirst.getEntry());
-        Assert.assertEquals(mFirst.getEntry(), mHeadsUpStatusBarView.getShowingEntry());
+        when(mHeadsUpManager.getTopEntry()).thenReturn(mEntry);
+        mHeadsUpAppearanceController.onHeadsUpPinned(mEntry);
+        assertEquals(mRow.getEntry(), mHeadsUpStatusBarView.getShowingEntry());
 
-        mFirst.setPinned(false);
+        mRow.setPinned(false);
         when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(false);
-        mHeadsUpAppearanceController.onHeadsUpUnPinned(mFirst.getEntry());
-        Assert.assertEquals(null, mHeadsUpStatusBarView.getShowingEntry());
+        mHeadsUpAppearanceController.onHeadsUpUnPinned(mEntry);
+        assertEquals(null, mHeadsUpStatusBarView.getShowingEntry());
     }
 
     @Test
     public void testShownUpdated() {
-        mFirst.setPinned(true);
+        mRow.setPinned(true);
         when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(true);
-        when(mHeadsUpManager.getTopEntry()).thenReturn(mFirst.getEntry());
-        mHeadsUpAppearanceController.onHeadsUpPinned(mFirst.getEntry());
-        Assert.assertTrue(mHeadsUpAppearanceController.isShown());
+        when(mHeadsUpManager.getTopEntry()).thenReturn(mEntry);
+        mHeadsUpAppearanceController.onHeadsUpPinned(mEntry);
+        assertTrue(mHeadsUpAppearanceController.isShown());
 
-        mFirst.setPinned(false);
+        mRow.setPinned(false);
         when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(false);
-        mHeadsUpAppearanceController.onHeadsUpUnPinned(mFirst.getEntry());
+        mHeadsUpAppearanceController.onHeadsUpUnPinned(mEntry);
         Assert.assertFalse(mHeadsUpAppearanceController.isShown());
     }
 
     @Test
     public void testHeaderUpdated() {
-        mFirst.setPinned(true);
+        mRow.setPinned(true);
         when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(true);
-        when(mHeadsUpManager.getTopEntry()).thenReturn(mFirst.getEntry());
-        mHeadsUpAppearanceController.onHeadsUpPinned(mFirst.getEntry());
-        Assert.assertEquals(mFirst.getHeaderVisibleAmount(), 0.0f, 0.0f);
+        when(mHeadsUpManager.getTopEntry()).thenReturn(mEntry);
+        mHeadsUpAppearanceController.onHeadsUpPinned(mEntry);
+        assertEquals(mRow.getHeaderVisibleAmount(), 0.0f, 0.0f);
 
-        mFirst.setPinned(false);
+        mRow.setPinned(false);
         when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(false);
-        mHeadsUpAppearanceController.onHeadsUpUnPinned(mFirst.getEntry());
-        Assert.assertEquals(mFirst.getHeaderVisibleAmount(), 1.0f, 0.0f);
+        mHeadsUpAppearanceController.onHeadsUpUnPinned(mEntry);
+        assertEquals(mRow.getHeaderVisibleAmount(), 1.0f, 0.0f);
     }
 
     @Test
     public void testOperatorNameViewUpdated() {
         mHeadsUpAppearanceController.setAnimationsEnabled(false);
 
-        mFirst.setPinned(true);
+        mRow.setPinned(true);
         when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(true);
-        when(mHeadsUpManager.getTopEntry()).thenReturn(mFirst.getEntry());
-        mHeadsUpAppearanceController.onHeadsUpPinned(mFirst.getEntry());
-        Assert.assertEquals(View.INVISIBLE, mOperatorNameView.getVisibility());
+        when(mHeadsUpManager.getTopEntry()).thenReturn(mEntry);
+        mHeadsUpAppearanceController.onHeadsUpPinned(mEntry);
+        assertEquals(View.INVISIBLE, mOperatorNameView.getVisibility());
 
-        mFirst.setPinned(false);
+        mRow.setPinned(false);
         when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(false);
-        mHeadsUpAppearanceController.onHeadsUpUnPinned(mFirst.getEntry());
-        Assert.assertEquals(View.VISIBLE, mOperatorNameView.getVisibility());
+        mHeadsUpAppearanceController.onHeadsUpUnPinned(mEntry);
+        assertEquals(View.VISIBLE, mOperatorNameView.getVisibility());
     }
 
     @Test
@@ -196,8 +204,8 @@
                 new Clock(mContext, null),
                 Optional.empty());
 
-        Assert.assertEquals(expandedHeight, newController.mExpandedHeight, 0.0f);
-        Assert.assertEquals(appearFraction, newController.mAppearFraction, 0.0f);
+        assertEquals(expandedHeight, newController.mExpandedHeight, 0.0f);
+        assertEquals(appearFraction, newController.mAppearFraction, 0.0f);
     }
 
     @Test
@@ -215,4 +223,68 @@
         verify(mPanelView).setHeadsUpAppearanceController(isNull());
         verify(mStackScrollerController).removeOnExpandedHeightChangedListener(any());
     }
+
+    @Test
+    public void testPulsingRoundness_onUpdateHeadsUpAndPulsingRoundness() {
+        // Pulsing: Enable flag and dozing
+        when(mNotificationRoundnessManager.shouldRoundNotificationPulsing()).thenReturn(true);
+        when(mTestHelper.getStatusBarStateController().isDozing()).thenReturn(true);
+
+        // Pulsing: Enabled
+        mRow.setHeadsUp(true);
+        mHeadsUpAppearanceController.updateHeadsUpAndPulsingRoundness(mEntry);
+
+        String debugString = mRow.getRoundableState().debugString();
+        assertEquals(
+                "If Pulsing is enabled, roundness should be set to 1. Value: " + debugString,
+                /* expected = */ 1,
+                /* actual = */ mRow.getTopRoundness(),
+                /* delta = */ 0.001
+        );
+        assertTrue(debugString.contains("Pulsing"));
+
+        // Pulsing: Disabled
+        mRow.setHeadsUp(false);
+        mHeadsUpAppearanceController.updateHeadsUpAndPulsingRoundness(mEntry);
+
+        assertEquals(
+                "If Pulsing is disabled, roundness should be set to 0. Value: "
+                        + mRow.getRoundableState().debugString(),
+                /* expected = */ 0,
+                /* actual = */ mRow.getTopRoundness(),
+                /* delta = */ 0.001
+        );
+    }
+
+    @Test
+    public void testPulsingRoundness_onHeadsUpStateChanged() {
+        // Pulsing: Enable flag and dozing
+        when(mNotificationRoundnessManager.shouldRoundNotificationPulsing()).thenReturn(true);
+        when(mTestHelper.getStatusBarStateController().isDozing()).thenReturn(true);
+
+        // Pulsing: Enabled
+        mEntry.setHeadsUp(true);
+        mHeadsUpAppearanceController.onHeadsUpStateChanged(mEntry, true);
+
+        String debugString = mRow.getRoundableState().debugString();
+        assertEquals(
+                "If Pulsing is enabled, roundness should be set to 1. Value: " + debugString,
+                /* expected = */ 1,
+                /* actual = */ mRow.getTopRoundness(),
+                /* delta = */ 0.001
+        );
+        assertTrue(debugString.contains("Pulsing"));
+
+        // Pulsing: Disabled
+        mEntry.setHeadsUp(false);
+        mHeadsUpAppearanceController.onHeadsUpStateChanged(mEntry, false);
+
+        assertEquals(
+                "If Pulsing is disabled, roundness should be set to 0. Value: "
+                        + mRow.getRoundableState().debugString(),
+                /* expected = */ 0,
+                /* actual = */ mRow.getTopRoundness(),
+                /* delta = */ 0.001
+        );
+    }
 }