[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
This commit is contained in:
@@ -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
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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,30 +38,25 @@ 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)
|
||||
ArgumentCaptor.forClass(ContentObserver::class.java)
|
||||
|
||||
@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) {
|
||||
1f
|
||||
} else {
|
||||
0f
|
||||
}
|
||||
ValueAnimator.setDurationScale(durationScale)
|
||||
val durationScale =
|
||||
if (enabled) {
|
||||
1f
|
||||
} else {
|
||||
0f
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user