summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java53
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/MultiSourceMinAlphaController.kt82
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java78
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/MultiSourceMinAlphaControllerTest.kt106
4 files changed, 260 insertions, 59 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
index fcae23b068bf..0d580792a9dc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
@@ -14,9 +14,6 @@
package com.android.systemui.statusbar.phone.fragment;
-import static com.android.systemui.statusbar.events.SystemStatusAnimationSchedulerKt.IDLE;
-import static com.android.systemui.statusbar.events.SystemStatusAnimationSchedulerKt.SHOWING_PERSISTENT_DOT;
-
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.app.Fragment;
@@ -39,6 +36,7 @@ import androidx.annotation.VisibleForTesting;
import androidx.core.animation.Animator;
import com.android.app.animation.Interpolators;
+import com.android.app.animation.InterpolatorsAndroidX;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.Dumpable;
import com.android.systemui.R;
@@ -77,6 +75,8 @@ import com.android.systemui.util.CarrierConfigTracker.CarrierConfigChangedListen
import com.android.systemui.util.CarrierConfigTracker.DefaultDataSubscriptionChangedListener;
import com.android.systemui.util.settings.SecureSettings;
+import kotlin.Unit;
+
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
@@ -99,12 +99,16 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
private static final String EXTRA_PANEL_STATE = "panel_state";
public static final String STATUS_BAR_ICON_MANAGER_TAG = "status_bar_icon_manager";
public static final int FADE_IN_DURATION = 320;
+ public static final int FADE_OUT_DURATION = 160;
public static final int FADE_IN_DELAY = 50;
+ private static final int SOURCE_SYSTEM_EVENT_ANIMATOR = 1;
+ private static final int SOURCE_OTHER = 2;
private StatusBarFragmentComponent mStatusBarFragmentComponent;
private PhoneStatusBarView mStatusBar;
private final StatusBarStateController mStatusBarStateController;
private final KeyguardStateController mKeyguardStateController;
private final ShadeViewController mShadeViewController;
+ private MultiSourceMinAlphaController mEndSideAlphaController;
private LinearLayout mEndSideContent;
private View mClockView;
private View mOngoingCallChip;
@@ -149,7 +153,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
}
};
private OperatorNameViewController mOperatorNameViewController;
- private StatusBarSystemEventAnimator mSystemEventAnimator;
+ private StatusBarSystemEventDefaultAnimator mSystemEventAnimator;
private final CarrierConfigChangedListener mCarrierConfigCallback =
new CarrierConfigChangedListener() {
@@ -297,14 +301,14 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
updateBlockedIcons();
mStatusBarIconController.addIconGroup(mDarkIconManager);
mEndSideContent = mStatusBar.findViewById(R.id.status_bar_end_side_content);
+ mEndSideAlphaController = new MultiSourceMinAlphaController(mEndSideContent);
mClockView = mStatusBar.findViewById(R.id.clock);
mOngoingCallChip = mStatusBar.findViewById(R.id.ongoing_call_chip);
showEndSideContent(false);
showClock(false);
initOperatorName();
initNotificationIconArea();
- mSystemEventAnimator =
- new StatusBarSystemEventAnimator(mEndSideContent, getResources());
+ mSystemEventAnimator = getSystemEventAnimator();
mCarrierConfigTracker.addCallback(mCarrierConfigCallback);
mCarrierConfigTracker.addDefaultDataSubscriptionChangedListener(mDefaultDataListener);
@@ -593,18 +597,27 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
}
private void hideEndSideContent(boolean animate) {
- animateHide(mEndSideContent, animate);
+ if (!animate) {
+ mEndSideAlphaController.setAlpha(/*alpha*/ 0f, SOURCE_OTHER);
+ } else {
+ mEndSideAlphaController.animateToAlpha(/*alpha*/ 0f, SOURCE_OTHER, FADE_OUT_DURATION,
+ InterpolatorsAndroidX.ALPHA_OUT, /*startDelay*/ 0);
+ }
}
private void showEndSideContent(boolean animate) {
- // Only show the system icon area if we are not currently animating
- int state = mAnimationScheduler.getAnimationState();
- if (state == IDLE || state == SHOWING_PERSISTENT_DOT) {
- animateShow(mEndSideContent, animate);
+ if (!animate) {
+ mEndSideAlphaController.setAlpha(1f, SOURCE_OTHER);
+ return;
+ }
+ if (mKeyguardStateController.isKeyguardFadingAway()) {
+ mEndSideAlphaController.animateToAlpha(/*alpha*/ 1f, SOURCE_OTHER,
+ mKeyguardStateController.getKeyguardFadingAwayDuration(),
+ InterpolatorsAndroidX.LINEAR_OUT_SLOW_IN,
+ mKeyguardStateController.getKeyguardFadingAwayDelay());
} else {
- // We are in the middle of a system status event animation, which will animate the
- // alpha (but not the visibility). Allow the view to become visible again
- mEndSideContent.setVisibility(View.VISIBLE);
+ mEndSideAlphaController.animateToAlpha(/*alpha*/ 1f, SOURCE_OTHER, FADE_IN_DURATION,
+ InterpolatorsAndroidX.ALPHA_IN, FADE_IN_DELAY);
}
}
@@ -671,7 +684,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
v.animate()
.alpha(0f)
- .setDuration(160)
+ .setDuration(FADE_OUT_DURATION)
.setStartDelay(0)
.setInterpolator(Interpolators.ALPHA_OUT)
.withEndAction(() -> v.setVisibility(state));
@@ -754,6 +767,16 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
return mSystemEventAnimator.onSystemEventAnimationFinish(hasPersistentDot);
}
+ private StatusBarSystemEventDefaultAnimator getSystemEventAnimator() {
+ return new StatusBarSystemEventDefaultAnimator(getResources(), (alpha) -> {
+ mEndSideAlphaController.setAlpha(alpha, SOURCE_SYSTEM_EVENT_ANIMATOR);
+ return Unit.INSTANCE;
+ }, (translationX) -> {
+ mEndSideContent.setTranslationX(translationX);
+ return Unit.INSTANCE;
+ }, /*isAnimationRunning*/ false);
+ }
+
private void updateStatusBarLocation(int left, int right) {
int leftMargin = left - mStatusBar.getLeft();
int rightMargin = mStatusBar.getRight() - right;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/MultiSourceMinAlphaController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/MultiSourceMinAlphaController.kt
new file mode 100644
index 000000000000..c8836e4235dc
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/MultiSourceMinAlphaController.kt
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone.fragment
+
+import android.view.View
+import androidx.core.animation.Interpolator
+import androidx.core.animation.ValueAnimator
+import com.android.app.animation.InterpolatorsAndroidX
+
+/**
+ * A controller that keeps track of multiple sources applying alpha value changes to a view. It will
+ * always apply the minimum alpha value of all sources.
+ */
+internal class MultiSourceMinAlphaController
+@JvmOverloads
+constructor(private val view: View, private val initialAlpha: Float = 1f) {
+
+ private val alphas = mutableMapOf<Int, Float>()
+ private val animators = mutableMapOf<Int, ValueAnimator>()
+
+ /**
+ * Sets the alpha of the provided source and applies it to the view (if no other source has set
+ * a lower alpha currently). If an animator of the same source is still running (i.e.
+ * [animateToAlpha] was called before), that animator is cancelled.
+ */
+ fun setAlpha(alpha: Float, sourceId: Int) {
+ animators[sourceId]?.cancel()
+ updateAlpha(alpha, sourceId)
+ }
+
+ /** Animates to the alpha of the provided source. */
+ fun animateToAlpha(
+ alpha: Float,
+ sourceId: Int,
+ duration: Long,
+ interpolator: Interpolator = InterpolatorsAndroidX.ALPHA_IN,
+ startDelay: Long = 0
+ ) {
+ animators[sourceId]?.cancel()
+ val animator = ValueAnimator.ofFloat(getMinAlpha(), alpha)
+ animator.duration = duration
+ animator.startDelay = startDelay
+ animator.interpolator = interpolator
+ animator.addUpdateListener { updateAlpha(animator.animatedValue as Float, sourceId) }
+ animator.start()
+ animators[sourceId] = animator
+ }
+
+ fun reset() {
+ alphas.clear()
+ animators.forEach { it.value.cancel() }
+ animators.clear()
+ applyAlphaToView()
+ }
+
+ private fun updateAlpha(alpha: Float, sourceId: Int) {
+ alphas[sourceId] = alpha
+ applyAlphaToView()
+ }
+
+ private fun applyAlphaToView() {
+ val minAlpha = getMinAlpha()
+ view.visibility = if (minAlpha != 0f) View.VISIBLE else View.INVISIBLE
+ view.alpha = minAlpha
+ }
+
+ private fun getMinAlpha() = alphas.minOfOrNull { it.value } ?: initialAlpha
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
index 9b1d93b691c3..5dcb90144b70 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
@@ -18,10 +18,6 @@ import static android.view.Display.DEFAULT_DISPLAY;
import static com.android.systemui.shade.ShadeExpansionStateManagerKt.STATE_CLOSED;
import static com.android.systemui.shade.ShadeExpansionStateManagerKt.STATE_OPEN;
-import static com.android.systemui.statusbar.events.SystemStatusAnimationSchedulerKt.ANIMATING_IN;
-import static com.android.systemui.statusbar.events.SystemStatusAnimationSchedulerKt.ANIMATING_OUT;
-import static com.android.systemui.statusbar.events.SystemStatusAnimationSchedulerKt.IDLE;
-import static com.android.systemui.statusbar.events.SystemStatusAnimationSchedulerKt.RUNNING_CHIP_ANIM;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -49,7 +45,7 @@ import android.view.View;
import android.view.ViewPropertyAnimator;
import android.widget.FrameLayout;
-import androidx.core.animation.Animator;
+import androidx.core.animation.AnimatorTestRule;
import androidx.test.filters.SmallTest;
import com.android.keyguard.KeyguardUpdateMonitor;
@@ -85,6 +81,7 @@ import com.android.systemui.util.settings.SecureSettings;
import com.android.systemui.util.time.FakeSystemClock;
import org.junit.Before;
+import org.junit.ClassRule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -139,6 +136,8 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
private StatusBarWindowStateController mStatusBarWindowStateController;
@Mock
private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+ @ClassRule
+ public static AnimatorTestRule mAnimatorTestRule = new AnimatorTestRule();
private List<StatusBarWindowStateListener> mStatusBarWindowStateListeners = new ArrayList<>();
@@ -172,7 +171,6 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
@Test
public void testDisableSystemInfo_systemAnimationIdle_doesHide() {
- when(mAnimationScheduler.getAnimationState()).thenReturn(IDLE);
CollapsedStatusBarFragment fragment = resumeAndGetFragment();
fragment.disable(DEFAULT_DISPLAY, StatusBarManager.DISABLE_SYSTEM_INFO, 0, false);
@@ -192,24 +190,26 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
public void testSystemStatusAnimation_startedDisabled_finishedWithAnimator_showsSystemInfo() {
// GIVEN the status bar hides the system info via disable flags, while there is no event
CollapsedStatusBarFragment fragment = resumeAndGetFragment();
- when(mAnimationScheduler.getAnimationState()).thenReturn(IDLE);
fragment.disable(DEFAULT_DISPLAY, StatusBarManager.DISABLE_SYSTEM_INFO, 0, false);
assertEquals(View.INVISIBLE, getEndSideContentView().getVisibility());
+ // WHEN the system event animation starts
+ fragment.onSystemEventAnimationBegin().start();
+
+ // THEN the view remains invisible during the animation
+ assertEquals(0f, getEndSideContentView().getAlpha(), 0.01);
+ mAnimatorTestRule.advanceTimeBy(500);
+ assertEquals(0f, getEndSideContentView().getAlpha(), 0.01);
+
// WHEN the disable flags are cleared during a system event animation
- when(mAnimationScheduler.getAnimationState()).thenReturn(RUNNING_CHIP_ANIM);
fragment.disable(DEFAULT_DISPLAY, 0, 0, false);
- // THEN the view is made visible again, but still low alpha
- assertEquals(View.VISIBLE, getEndSideContentView().getVisibility());
+ // THEN the view remains invisible
assertEquals(0, getEndSideContentView().getAlpha(), 0.01);
// WHEN the system event animation finishes
- when(mAnimationScheduler.getAnimationState()).thenReturn(ANIMATING_OUT);
- Animator anim = fragment.onSystemEventAnimationFinish(false);
- anim.start();
- processAllMessages();
- anim.end();
+ fragment.onSystemEventAnimationFinish(false).start();
+ mAnimatorTestRule.advanceTimeBy(500);
// THEN the system info is full alpha
assertEquals(1, getEndSideContentView().getAlpha(), 0.01);
@@ -219,20 +219,15 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
public void testSystemStatusAnimation_systemInfoDisabled_staysInvisible() {
// GIVEN the status bar hides the system info via disable flags, while there is no event
CollapsedStatusBarFragment fragment = resumeAndGetFragment();
- when(mAnimationScheduler.getAnimationState()).thenReturn(IDLE);
fragment.disable(DEFAULT_DISPLAY, StatusBarManager.DISABLE_SYSTEM_INFO, 0, false);
assertEquals(View.INVISIBLE, getEndSideContentView().getVisibility());
// WHEN the system event animation finishes
- when(mAnimationScheduler.getAnimationState()).thenReturn(ANIMATING_OUT);
- Animator anim = fragment.onSystemEventAnimationFinish(false);
- anim.start();
- processAllMessages();
- anim.end();
+ fragment.onSystemEventAnimationFinish(false).start();
+ mAnimatorTestRule.advanceTimeBy(500);
- // THEN the system info is at full alpha, but still INVISIBLE (since the disable flag is
- // still set)
- assertEquals(1, getEndSideContentView().getAlpha(), 0.01);
+ // THEN the system info remains invisible (since the disable flag is still set)
+ assertEquals(0, getEndSideContentView().getAlpha(), 0.01);
assertEquals(View.INVISIBLE, getEndSideContentView().getVisibility());
}
@@ -241,15 +236,14 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
public void testSystemStatusAnimation_notDisabled_animatesAlphaZero() {
// GIVEN the status bar is not disabled
CollapsedStatusBarFragment fragment = resumeAndGetFragment();
- when(mAnimationScheduler.getAnimationState()).thenReturn(ANIMATING_IN);
+ assertEquals(1, getEndSideContentView().getAlpha(), 0.01);
+
// WHEN the system event animation begins
- Animator anim = fragment.onSystemEventAnimationBegin();
- anim.start();
- processAllMessages();
- anim.end();
+ fragment.onSystemEventAnimationBegin().start();
+ mAnimatorTestRule.advanceTimeBy(500);
- // THEN the system info is visible but alpha 0
- assertEquals(View.VISIBLE, getEndSideContentView().getVisibility());
+ // THEN the system info is invisible
+ assertEquals(View.INVISIBLE, getEndSideContentView().getVisibility());
assertEquals(0, getEndSideContentView().getAlpha(), 0.01);
}
@@ -257,25 +251,21 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
public void testSystemStatusAnimation_notDisabled_animatesBackToAlphaOne() {
// GIVEN the status bar is not disabled
CollapsedStatusBarFragment fragment = resumeAndGetFragment();
- when(mAnimationScheduler.getAnimationState()).thenReturn(ANIMATING_IN);
+ assertEquals(1, getEndSideContentView().getAlpha(), 0.01);
+
// WHEN the system event animation begins
- Animator anim = fragment.onSystemEventAnimationBegin();
- anim.start();
- processAllMessages();
- anim.end();
+ fragment.onSystemEventAnimationBegin().start();
+ mAnimatorTestRule.advanceTimeBy(500);
- // THEN the system info is visible but alpha 0
- assertEquals(View.VISIBLE, getEndSideContentView().getVisibility());
+ // THEN the system info is invisible
+ assertEquals(View.INVISIBLE, getEndSideContentView().getVisibility());
assertEquals(0, getEndSideContentView().getAlpha(), 0.01);
// WHEN the system event animation finishes
- when(mAnimationScheduler.getAnimationState()).thenReturn(ANIMATING_OUT);
- anim = fragment.onSystemEventAnimationFinish(false);
- anim.start();
- processAllMessages();
- anim.end();
+ fragment.onSystemEventAnimationFinish(false).start();
+ mAnimatorTestRule.advanceTimeBy(500);
- // THEN the syste info is full alpha and VISIBLE
+ // THEN the system info is full alpha and VISIBLE
assertEquals(View.VISIBLE, getEndSideContentView().getVisibility());
assertEquals(1, getEndSideContentView().getAlpha(), 0.01);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/MultiSourceMinAlphaControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/MultiSourceMinAlphaControllerTest.kt
new file mode 100644
index 000000000000..2617613d1fc5
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/MultiSourceMinAlphaControllerTest.kt
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone.fragment
+
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.view.View
+import androidx.core.animation.AnimatorTestRule
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import junit.framework.Assert.assertEquals
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+private const val TEST_SOURCE_1 = 1
+private const val TEST_SOURCE_2 = 2
+private const val TEST_ANIMATION_DURATION = 100L
+private const val INITIAL_ALPHA = 1f
+
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+@SmallTest
+class MultiSourceMinAlphaControllerTest : SysuiTestCase() {
+
+ private val view = View(context)
+ private val multiSourceMinAlphaController =
+ MultiSourceMinAlphaController(view, initialAlpha = INITIAL_ALPHA)
+
+ @get:Rule val animatorTestRule = AnimatorTestRule()
+
+ @Before
+ fun setup() {
+ multiSourceMinAlphaController.reset()
+ }
+
+ @Test
+ fun testSetAlpha() {
+ multiSourceMinAlphaController.setAlpha(alpha = 0.5f, sourceId = TEST_SOURCE_1)
+ assertEquals(0.5f, view.alpha)
+ }
+
+ @Test
+ fun testAnimateToAlpha() {
+ multiSourceMinAlphaController.animateToAlpha(
+ alpha = 0.5f,
+ sourceId = TEST_SOURCE_1,
+ duration = TEST_ANIMATION_DURATION
+ )
+ animatorTestRule.advanceTimeBy(TEST_ANIMATION_DURATION)
+ assertEquals(0.5f, view.alpha)
+ }
+
+ @Test
+ fun testReset() {
+ multiSourceMinAlphaController.animateToAlpha(
+ alpha = 0.5f,
+ sourceId = TEST_SOURCE_1,
+ duration = TEST_ANIMATION_DURATION
+ )
+ multiSourceMinAlphaController.setAlpha(alpha = 0.7f, sourceId = TEST_SOURCE_2)
+ multiSourceMinAlphaController.reset()
+ // advance time to ensure that animators are cancelled when the controller is reset
+ animatorTestRule.advanceTimeBy(TEST_ANIMATION_DURATION)
+ assertEquals(INITIAL_ALPHA, view.alpha)
+ }
+
+ @Test
+ fun testMinOfTwoSourcesIsApplied() {
+ multiSourceMinAlphaController.setAlpha(alpha = 0f, sourceId = TEST_SOURCE_1)
+ multiSourceMinAlphaController.setAlpha(alpha = 0.5f, sourceId = TEST_SOURCE_2)
+ assertEquals(0f, view.alpha)
+ multiSourceMinAlphaController.setAlpha(alpha = 1f, sourceId = TEST_SOURCE_1)
+ assertEquals(0.5f, view.alpha)
+ }
+
+ @Test
+ fun testSetAlphaForSameSourceCancelsAnimator() {
+ multiSourceMinAlphaController.animateToAlpha(
+ alpha = 0f,
+ sourceId = TEST_SOURCE_1,
+ duration = TEST_ANIMATION_DURATION
+ )
+ animatorTestRule.advanceTimeBy(TEST_ANIMATION_DURATION / 2)
+ multiSourceMinAlphaController.setAlpha(alpha = 1f, sourceId = TEST_SOURCE_1)
+ animatorTestRule.advanceTimeBy(TEST_ANIMATION_DURATION / 2)
+ // verify that animation was cancelled and the setAlpha call overrides the alpha value of
+ // the animation
+ assertEquals(1f, view.alpha)
+ }
+}