Reload StackStateAnimator resources on configuration changes

Fixes: 317061579
Test: atest StackStateAnimatorTest
Flag: NA
Change-Id: Ib88867339c5fbf1265f704e541b84cd81cbb67ce
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 42b56e7..ebe7fb0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -233,7 +233,7 @@
     private final ArrayList<AnimationEvent> mAnimationEvents = new ArrayList<>();
     private final ArrayList<View> mSwipedOutViews = new ArrayList<>();
     private NotificationStackSizeCalculator mNotificationStackSizeCalculator;
-    private final StackStateAnimator mStateAnimator = new StackStateAnimator(this);
+    private final StackStateAnimator mStateAnimator;
     private boolean mAnimationsEnabled;
     private boolean mChangePositionInProgress;
     private boolean mChildTransferInProgress;
@@ -670,6 +670,7 @@
         mExpandHelper.setScrollAdapter(mScrollAdapter);
 
         mStackScrollAlgorithm = createStackScrollAlgorithm(context);
+        mStateAnimator = new StackStateAnimator(context, this);
         mShouldDrawNotificationBackground =
                 res.getBoolean(R.bool.config_drawNotificationBackground);
         setOutlineProvider(mOutlineProvider);
@@ -1083,6 +1084,7 @@
         }
         mGapHeight = res.getDimensionPixelSize(R.dimen.notification_section_divider_height);
         mStackScrollAlgorithm.initView(context);
+        mStateAnimator.initView(context);
         mAmbientState.reload(context);
         mPaddingBetweenElements = Math.max(1,
                 res.getDimensionPixelSize(R.dimen.notification_divider_height));
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
index fb14a91..ab62ed6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
@@ -23,6 +23,7 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
+import android.content.Context;
 import android.util.Property;
 import android.view.View;
 
@@ -66,9 +67,8 @@
     public static final int DELAY_EFFECT_MAX_INDEX_DIFFERENCE = 2;
     private static final int MAX_STAGGER_COUNT = 5;
 
-    private final int mGoToFullShadeAppearingTranslation;
-    @VisibleForTesting
-    float mHeadsUpAppearStartAboveScreen;
+    @VisibleForTesting int mGoToFullShadeAppearingTranslation;
+    @VisibleForTesting float mHeadsUpAppearStartAboveScreen;
     private final ExpandableViewState mTmpState = new ExpandableViewState();
     private final AnimationProperties mAnimationProperties;
     public NotificationStackScrollLayout mHostLayout;
@@ -92,14 +92,9 @@
     private NotificationShelf mShelf;
     private StackStateLogger mLogger;
 
-    public StackStateAnimator(NotificationStackScrollLayout hostLayout) {
+    public StackStateAnimator(Context context, NotificationStackScrollLayout hostLayout) {
         mHostLayout = hostLayout;
-        // TODO(b/317061579) reload on configuration changes
-        mGoToFullShadeAppearingTranslation =
-                hostLayout.getContext().getResources().getDimensionPixelSize(
-                        R.dimen.go_to_full_shade_appearing_translation);
-        mHeadsUpAppearStartAboveScreen = hostLayout.getContext().getResources()
-                .getDimensionPixelSize(R.dimen.heads_up_appear_y_above_screen);
+        initView(context);
         mAnimationProperties = new AnimationProperties() {
             @Override
             public AnimationFilter getAnimationFilter() {
@@ -118,6 +113,21 @@
         };
     }
 
+    /**
+     * Needs to be called on configuration changes, to update cached resource values.
+     */
+    public void initView(Context context) {
+        updateResources(context);
+    }
+
+    private void updateResources(Context context) {
+        mGoToFullShadeAppearingTranslation =
+                context.getResources().getDimensionPixelSize(
+                        R.dimen.go_to_full_shade_appearing_translation);
+        mHeadsUpAppearStartAboveScreen = context.getResources()
+                .getDimensionPixelSize(R.dimen.heads_up_appear_y_above_screen);
+    }
+
     protected void setLogger(StackStateLogger logger) {
         mLogger = logger;
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackStateAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackStateAnimatorTest.kt
index 3d90cd2..dfbe1ac 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackStateAnimatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackStateAnimatorTest.kt
@@ -21,6 +21,7 @@
 import android.testing.TestableLooper.RunWithLooper
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.res.R
 import com.android.systemui.statusbar.notification.row.ExpandableView
 import com.android.systemui.statusbar.notification.shared.NotificationsImprovedHunAnimation
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.AnimationEvent
@@ -29,6 +30,7 @@
 import com.android.systemui.util.mockito.argumentCaptor
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -39,6 +41,8 @@
 import org.mockito.Mockito.verify
 
 private const val VIEW_HEIGHT = 100
+private const val FULL_SHADE_APPEAR_TRANSLATION = 300
+private const val HEADS_UP_ABOVE_SCREEN = 80
 
 @SmallTest
 @RunWith(AndroidTestingRunner::class)
@@ -53,9 +57,15 @@
     private val runnableCaptor: ArgumentCaptor<Runnable> = argumentCaptor()
     @Before
     fun setUp() {
+        overrideResource(
+            R.dimen.go_to_full_shade_appearing_translation,
+            FULL_SHADE_APPEAR_TRANSLATION
+        )
+        overrideResource(R.dimen.heads_up_appear_y_above_screen, HEADS_UP_ABOVE_SCREEN)
+
         whenever(stackScroller.context).thenReturn(context)
         whenever(view.viewState).thenReturn(viewState)
-        stackStateAnimator = StackStateAnimator(stackScroller)
+        stackStateAnimator = StackStateAnimator(mContext, stackScroller)
     }
 
     @Test
@@ -124,4 +134,22 @@
         verify(view, description("should be called at the end of the animation"))
             .removeFromTransientContainer()
     }
+
+    @Test
+    fun initView_updatesResources() {
+        // Given: the resource values are initialized in the SSA
+        assertThat(stackStateAnimator.mGoToFullShadeAppearingTranslation)
+            .isEqualTo(FULL_SHADE_APPEAR_TRANSLATION)
+        assertThat(stackStateAnimator.mHeadsUpAppearStartAboveScreen)
+            .isEqualTo(HEADS_UP_ABOVE_SCREEN)
+
+        // When: initView is called after the resources have changed
+        overrideResource(R.dimen.go_to_full_shade_appearing_translation, 200)
+        overrideResource(R.dimen.heads_up_appear_y_above_screen, 100)
+        stackStateAnimator.initView(mContext)
+
+        // Then: the resource values are updated
+        assertThat(stackStateAnimator.mGoToFullShadeAppearingTranslation).isEqualTo(200)
+        assertThat(stackStateAnimator.mHeadsUpAppearStartAboveScreen).isEqualTo(100)
+    }
 }