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

Commit 982c56f6 authored by Nick Chameyev's avatar Nick Chameyev
Browse files

[Unfold animation] Get animation scale from content provider

ValueAnimator#areAnimationsEnabled() method does not
reflect the latest state of the animation scale
at the time when content provider emitted an update.
It led to a bug after disabling and enabling
animations: we added the unfold overlay in the
 UnfoldLightRevealOverlayAnimation (as animations
enabled) but didn't remove it because the transition
progress provider never reported animation start,
progress and finish events.

Changed to use the content provider to get
the latest state of the animation scale.

Bug: 256072006
Test: manual fold/unfolds after enabling/disabling talkback
Test: com.android.systemui.unfold.util.ScaleAwareUnfoldProgressProviderTest
Change-Id: If5d982791b9f8103ecfd8db44e24d2486560d4f5
parent c3de1864
Loading
Loading
Loading
Loading
+10 −9
Original line number Diff line number Diff line
@@ -15,7 +15,7 @@
 */
package com.android.systemui.unfold

import android.animation.ValueAnimator
import android.content.ContentResolver
import android.content.Context
import android.graphics.PixelFormat
import android.hardware.devicestate.DeviceStateManager
@@ -39,6 +39,7 @@ import com.android.systemui.statusbar.LightRevealScrim
import com.android.systemui.statusbar.LinearLightRevealEffect
import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
import com.android.systemui.unfold.updates.RotationChangeProvider
import com.android.systemui.unfold.util.ScaleAwareTransitionProgressProvider.Companion.areAnimationsEnabled
import com.android.systemui.util.traceSection
import com.android.wm.shell.displayareahelper.DisplayAreaHelper
import java.util.Optional
@@ -52,6 +53,7 @@ class UnfoldLightRevealOverlayAnimation
constructor(
    private val context: Context,
    private val deviceStateManager: DeviceStateManager,
    private val contentResolver: ContentResolver,
    private val displayManager: DisplayManager,
    private val unfoldTransitionProgressProvider: UnfoldTransitionProgressProvider,
    private val displayAreaHelper: Optional<DisplayAreaHelper>,
@@ -117,7 +119,7 @@ constructor(
        Trace.beginSection("UnfoldLightRevealOverlayAnimation#onScreenTurningOn")
        try {
            // Add the view only if we are unfolding and this is the first screen on
            if (!isFolded && !isUnfoldHandled && ValueAnimator.areAnimatorsEnabled()) {
            if (!isFolded && !isUnfoldHandled && contentResolver.areAnimationsEnabled()) {
                addView(onOverlayReady)
                isUnfoldHandled = true
            } else {
@@ -162,11 +164,10 @@ constructor(
                // blocker (turn on the brightness) only when the content is actually visible as it
                // might be presented only in the next frame.
                // See b/197538198
                transaction
                    .setFrameTimelineVsync(vsyncId)
                    .apply()
                transaction.setFrameTimelineVsync(vsyncId).apply()

                transaction.setFrameTimelineVsync(vsyncId + 1)
                transaction
                    .setFrameTimelineVsync(vsyncId + 1)
                    .addTransactionCommittedListener(backgroundExecutor) {
                        Trace.endAsyncSection("UnfoldLightRevealOverlayAnimation#relayout", 0)
                        callback.run()
@@ -218,8 +219,7 @@ constructor(
    }

    private fun getUnfoldedDisplayInfo(): DisplayInfo =
        displayManager
            .displays
        displayManager.displays
            .asSequence()
            .map { DisplayInfo().apply { it.getDisplayInfo(this) } }
            .filter { it.type == Display.TYPE_INTERNAL }
@@ -266,5 +266,6 @@ constructor(
                    isUnfoldHandled = false
                }
                this.isFolded = isFolded
            })
            }
        )
}
+24 −21
Original line number Diff line number Diff line
@@ -15,14 +15,13 @@
 */
package com.android.systemui.unfold.util

import android.animation.ValueAnimator
import android.content.ContentResolver
import android.database.ContentObserver
import android.provider.Settings
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.unfold.TestUnfoldTransitionProvider
import com.android.systemui.unfold.UnfoldTransitionProgressProvider
import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
import com.android.systemui.util.mockito.any
import org.junit.Before
@@ -30,6 +29,7 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
import org.mockito.Mock
import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyNoMoreInteractions
import org.mockito.MockitoAnnotations
@@ -38,15 +38,12 @@ import org.mockito.MockitoAnnotations
@SmallTest
class ScaleAwareUnfoldProgressProviderTest : SysuiTestCase() {

    @Mock
    lateinit var contentResolver: ContentResolver

    @Mock
    lateinit var sinkProvider: TransitionProgressListener
    @Mock lateinit var sinkProvider: TransitionProgressListener

    private val sourceProvider = TestUnfoldTransitionProvider()

    lateinit var progressProvider: ScaleAwareTransitionProgressProvider
    private lateinit var contentResolver: ContentResolver
    private lateinit var progressProvider: ScaleAwareTransitionProgressProvider

    private val animatorDurationScaleListenerCaptor =
        ArgumentCaptor.forClass(ContentObserver::class.java)
@@ -54,14 +51,12 @@ class ScaleAwareUnfoldProgressProviderTest : SysuiTestCase() {
    @Before
    fun setUp() {
        MockitoAnnotations.initMocks(this)
        contentResolver = spy(context.contentResolver)

        progressProvider = ScaleAwareTransitionProgressProvider(
                sourceProvider,
                contentResolver
        )
        progressProvider = ScaleAwareTransitionProgressProvider(sourceProvider, contentResolver)

        verify(contentResolver).registerContentObserver(any(), any(),
                animatorDurationScaleListenerCaptor.capture())
        verify(contentResolver)
            .registerContentObserver(any(), any(), animatorDurationScaleListenerCaptor.capture())

        progressProvider.addCallback(sinkProvider)
    }
@@ -121,12 +116,20 @@ class ScaleAwareUnfoldProgressProviderTest : SysuiTestCase() {
    }

    private fun setAnimationsEnabled(enabled: Boolean) {
        val durationScale = if (enabled) {
        val durationScale =
            if (enabled) {
                1f
            } else {
                0f
            }
        ValueAnimator.setDurationScale(durationScale)

        // It uses [TestableSettingsProvider] and it will be cleared after the test
        Settings.Global.putString(
            contentResolver,
            Settings.Global.ANIMATOR_DURATION_SCALE,
            durationScale.toString()
        )

        animatorDurationScaleListenerCaptor.value.dispatchChange(/* selfChange= */false)
    }
}
+19 −4
Original line number Diff line number Diff line
@@ -14,7 +14,6 @@
 */
package com.android.systemui.unfold.util

import android.animation.ValueAnimator
import android.content.ContentResolver
import android.database.ContentObserver
import android.provider.Settings
@@ -46,13 +45,15 @@ constructor(
        contentResolver.registerContentObserver(
            Settings.Global.getUriFor(Settings.Global.ANIMATOR_DURATION_SCALE),
            /* notifyForDescendants= */ false,
            animatorDurationScaleObserver)
            animatorDurationScaleObserver
        )
        onAnimatorScaleChanged()
    }

    private fun onAnimatorScaleChanged() {
        val animationsEnabled = ValueAnimator.areAnimatorsEnabled()
        scopedUnfoldTransitionProgressProvider.setReadyToHandleTransition(animationsEnabled)
        scopedUnfoldTransitionProgressProvider.setReadyToHandleTransition(
            contentResolver.areAnimationsEnabled()
        )
    }

    override fun addCallback(listener: TransitionProgressListener) {
@@ -74,4 +75,18 @@ constructor(
            progressProvider: UnfoldTransitionProgressProvider
        ): ScaleAwareTransitionProgressProvider
    }

    companion object {
        fun ContentResolver.areAnimationsEnabled(): Boolean {
            val animationScale =
                Settings.Global.getStringForUser(
                        this,
                        Settings.Global.ANIMATOR_DURATION_SCALE,
                        this.userId
                    )
                    ?.toFloatOrNull()
                    ?: 1f
            return animationScale != 0f
        }
    }
}