Have turbulence noise play together with ripple on UMO button click.
Note that there will be follow up CLs for polish the look. Bug: 281032715 Test: Manual & MediaControlPanelTest, MultiRippleControllerTest Change-Id: Id71f3ed5830b442d62e08328d87516d5dd5a00e9
This commit is contained in:
@@ -21,20 +21,9 @@ import androidx.annotation.VisibleForTesting
|
||||
/** Controller that handles playing [RippleAnimation]. */
|
||||
class MultiRippleController(private val multipleRippleView: MultiRippleView) {
|
||||
|
||||
private val ripplesFinishedListeners = ArrayList<RipplesFinishedListener>()
|
||||
|
||||
companion object {
|
||||
/** Max number of ripple animations at a time. */
|
||||
@VisibleForTesting const val MAX_RIPPLE_NUMBER = 10
|
||||
|
||||
interface RipplesFinishedListener {
|
||||
/** Triggered when all the ripples finish running. */
|
||||
fun onRipplesFinish()
|
||||
}
|
||||
}
|
||||
|
||||
fun addRipplesFinishedListener(listener: RipplesFinishedListener) {
|
||||
ripplesFinishedListeners.add(listener)
|
||||
}
|
||||
|
||||
/** Updates all the ripple colors during the animation. */
|
||||
@@ -52,9 +41,6 @@ class MultiRippleController(private val multipleRippleView: MultiRippleView) {
|
||||
rippleAnimation.play {
|
||||
// Remove ripple once the animation is done
|
||||
multipleRippleView.ripples.remove(rippleAnimation)
|
||||
if (multipleRippleView.ripples.isEmpty()) {
|
||||
ripplesFinishedListeners.forEach { listener -> listener.onRipplesFinish() }
|
||||
}
|
||||
}
|
||||
|
||||
// Trigger drawing
|
||||
|
||||
@@ -244,9 +244,10 @@ public class MediaControlPanel {
|
||||
private MultiRippleController mMultiRippleController;
|
||||
private TurbulenceNoiseController mTurbulenceNoiseController;
|
||||
private final FeatureFlags mFeatureFlags;
|
||||
|
||||
// TODO(b/281032715): Consider making this as a final variable. For now having a null check
|
||||
// due to unit test failure. (Perhaps missing some setup)
|
||||
private TurbulenceNoiseAnimationConfig mTurbulenceNoiseAnimationConfig;
|
||||
@VisibleForTesting
|
||||
MultiRippleController.Companion.RipplesFinishedListener mRipplesFinishedListener;
|
||||
|
||||
/**
|
||||
* Initialize a new control panel
|
||||
@@ -433,18 +434,6 @@ public class MediaControlPanel {
|
||||
MultiRippleView multiRippleView = vh.getMultiRippleView();
|
||||
mMultiRippleController = new MultiRippleController(multiRippleView);
|
||||
mTurbulenceNoiseController = new TurbulenceNoiseController(vh.getTurbulenceNoiseView());
|
||||
if (mFeatureFlags.isEnabled(Flags.UMO_TURBULENCE_NOISE)) {
|
||||
mRipplesFinishedListener = () -> {
|
||||
if (mTurbulenceNoiseAnimationConfig == null) {
|
||||
mTurbulenceNoiseAnimationConfig = createTurbulenceNoiseAnimation();
|
||||
}
|
||||
// Color will be correctly updated in ColorSchemeTransition.
|
||||
mTurbulenceNoiseController.play(mTurbulenceNoiseAnimationConfig);
|
||||
mMainExecutor.executeDelayed(
|
||||
mTurbulenceNoiseController::finish, TURBULENCE_NOISE_PLAY_DURATION);
|
||||
};
|
||||
mMultiRippleController.addRipplesFinishedListener(mRipplesFinishedListener);
|
||||
}
|
||||
|
||||
mColorSchemeTransition = new ColorSchemeTransition(
|
||||
mContext, mMediaViewHolder, mMultiRippleController, mTurbulenceNoiseController);
|
||||
@@ -1150,6 +1139,18 @@ public class MediaControlPanel {
|
||||
action.run();
|
||||
if (mFeatureFlags.isEnabled(Flags.UMO_SURFACE_RIPPLE)) {
|
||||
mMultiRippleController.play(createTouchRippleAnimation(button));
|
||||
if (mFeatureFlags.isEnabled(Flags.UMO_TURBULENCE_NOISE)) {
|
||||
if (mTurbulenceNoiseAnimationConfig == null) {
|
||||
mTurbulenceNoiseAnimationConfig =
|
||||
createTurbulenceNoiseAnimation();
|
||||
}
|
||||
// Color will be correctly updated in ColorSchemeTransition.
|
||||
mTurbulenceNoiseController.play(mTurbulenceNoiseAnimationConfig);
|
||||
mMainExecutor.executeDelayed(
|
||||
mTurbulenceNoiseController::finish,
|
||||
TURBULENCE_NOISE_PLAY_DURATION
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (icon instanceof Animatable) {
|
||||
@@ -1203,10 +1204,8 @@ public class MediaControlPanel {
|
||||
/* width= */ mMediaViewHolder.getMultiRippleView().getWidth(),
|
||||
/* height= */ mMediaViewHolder.getMultiRippleView().getHeight(),
|
||||
TurbulenceNoiseAnimationConfig.DEFAULT_MAX_DURATION_IN_MILLIS,
|
||||
/* easeInDuration= */
|
||||
TurbulenceNoiseAnimationConfig.DEFAULT_EASING_DURATION_IN_MILLIS,
|
||||
/* easeOutDuration= */
|
||||
TurbulenceNoiseAnimationConfig.DEFAULT_EASING_DURATION_IN_MILLIS,
|
||||
/* easeInDuration= */ 2500f,
|
||||
/* easeOutDuration= */ 2500f,
|
||||
this.getContext().getResources().getDisplayMetrics().density,
|
||||
BlendMode.PLUS,
|
||||
/* onAnimationEnd= */ null
|
||||
|
||||
@@ -2375,36 +2375,28 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
||||
assertThat(viewHolder.multiRippleView.ripples.size).isEqualTo(0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun onButtonClick_turbulenceNoiseFlagEnabled_createsRipplesFinishedListener() {
|
||||
fakeFeatureFlag.set(Flags.UMO_SURFACE_RIPPLE, true)
|
||||
fakeFeatureFlag.set(Flags.UMO_TURBULENCE_NOISE, true)
|
||||
|
||||
player.attachPlayer(viewHolder)
|
||||
|
||||
assertThat(player.mRipplesFinishedListener).isNotNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun onButtonClick_turbulenceNoiseFlagDisabled_doesNotCreateRipplesFinishedListener() {
|
||||
fakeFeatureFlag.set(Flags.UMO_SURFACE_RIPPLE, true)
|
||||
fakeFeatureFlag.set(Flags.UMO_TURBULENCE_NOISE, false)
|
||||
|
||||
player.attachPlayer(viewHolder)
|
||||
|
||||
assertThat(player.mRipplesFinishedListener).isNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun playTurbulenceNoise_finishesAfterDuration() {
|
||||
fakeFeatureFlag.set(Flags.UMO_SURFACE_RIPPLE, true)
|
||||
fakeFeatureFlag.set(Flags.UMO_TURBULENCE_NOISE, true)
|
||||
|
||||
val semanticActions =
|
||||
MediaButton(
|
||||
playOrPause =
|
||||
MediaAction(
|
||||
icon = null,
|
||||
action = {},
|
||||
contentDescription = "play",
|
||||
background = null
|
||||
)
|
||||
)
|
||||
val data = mediaData.copy(semanticActions = semanticActions)
|
||||
player.attachPlayer(viewHolder)
|
||||
player.bindPlayer(data, KEY)
|
||||
|
||||
viewHolder.actionPlayPause.callOnClick()
|
||||
|
||||
mainExecutor.execute {
|
||||
player.mRipplesFinishedListener.onRipplesFinish()
|
||||
|
||||
assertThat(turbulenceNoiseView.visibility).isEqualTo(View.VISIBLE)
|
||||
|
||||
clock.advanceTime(
|
||||
|
||||
@@ -101,52 +101,4 @@ class MultiRippleControllerTest : SysuiTestCase() {
|
||||
assertThat(multiRippleView.ripples.size).isEqualTo(0)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun play_onFinishesAllRipples_triggersRipplesFinished() {
|
||||
var isTriggered = false
|
||||
val listener =
|
||||
object : MultiRippleController.Companion.RipplesFinishedListener {
|
||||
override fun onRipplesFinish() {
|
||||
isTriggered = true
|
||||
}
|
||||
}
|
||||
multiRippleController.addRipplesFinishedListener(listener)
|
||||
|
||||
fakeExecutor.execute {
|
||||
multiRippleController.play(RippleAnimation(RippleAnimationConfig(duration = 1000)))
|
||||
multiRippleController.play(RippleAnimation(RippleAnimationConfig(duration = 2000)))
|
||||
|
||||
assertThat(multiRippleView.ripples.size).isEqualTo(2)
|
||||
|
||||
fakeSystemClock.advanceTime(2000L)
|
||||
|
||||
assertThat(multiRippleView.ripples.size).isEqualTo(0)
|
||||
assertThat(isTriggered).isTrue()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun play_notAllRipplesFinished_doesNotTriggerRipplesFinished() {
|
||||
var isTriggered = false
|
||||
val listener =
|
||||
object : MultiRippleController.Companion.RipplesFinishedListener {
|
||||
override fun onRipplesFinish() {
|
||||
isTriggered = true
|
||||
}
|
||||
}
|
||||
multiRippleController.addRipplesFinishedListener(listener)
|
||||
|
||||
fakeExecutor.execute {
|
||||
multiRippleController.play(RippleAnimation(RippleAnimationConfig(duration = 1000)))
|
||||
multiRippleController.play(RippleAnimation(RippleAnimationConfig(duration = 2000)))
|
||||
|
||||
assertThat(multiRippleView.ripples.size).isEqualTo(2)
|
||||
|
||||
fakeSystemClock.advanceTime(1000L)
|
||||
|
||||
assertThat(multiRippleView.ripples.size).isEqualTo(1)
|
||||
assertThat(isTriggered).isFalse()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user