Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d401bb91 authored by Yein Jo's avatar Yein Jo Committed by Android (Google) Code Review
Browse files

Merge "Have turbulence noise play together with ripple on UMO button click." into udc-dev

parents c0643ead cbb4ba95
Loading
Loading
Loading
Loading
+0 −14
Original line number Diff line number Diff line
@@ -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
+17 −18
Original line number Diff line number Diff line
@@ -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
+14 −22
Original line number Diff line number Diff line
@@ -2381,36 +2381,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)

        mainExecutor.execute {
            player.mRipplesFinishedListener.onRipplesFinish()
        viewHolder.actionPlayPause.callOnClick()

        mainExecutor.execute {
            assertThat(turbulenceNoiseView.visibility).isEqualTo(View.VISIBLE)

            clock.advanceTime(
+0 −48
Original line number Diff line number Diff line
@@ -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()
        }
    }
}