Merge "Disable unfold animation when animations disabled" into sc-v2-dev am: b6815ae344
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/16378723 Change-Id: I1febabbf23ade790a957a9000eed1a1edf2f980a
This commit is contained in:
@@ -26,6 +26,7 @@ import com.android.systemui.unfold.config.ResourceUnfoldTransitionConfig
|
|||||||
import com.android.systemui.unfold.config.UnfoldTransitionConfig
|
import com.android.systemui.unfold.config.UnfoldTransitionConfig
|
||||||
import com.android.systemui.unfold.progress.FixedTimingTransitionProgressProvider
|
import com.android.systemui.unfold.progress.FixedTimingTransitionProgressProvider
|
||||||
import com.android.systemui.unfold.progress.PhysicsBasedUnfoldTransitionProgressProvider
|
import com.android.systemui.unfold.progress.PhysicsBasedUnfoldTransitionProgressProvider
|
||||||
|
import com.android.systemui.unfold.util.ScaleAwareTransitionProgressProvider
|
||||||
import com.android.systemui.unfold.updates.DeviceFoldStateProvider
|
import com.android.systemui.unfold.updates.DeviceFoldStateProvider
|
||||||
import com.android.systemui.unfold.updates.hinge.EmptyHingeAngleProvider
|
import com.android.systemui.unfold.updates.hinge.EmptyHingeAngleProvider
|
||||||
import com.android.systemui.unfold.updates.hinge.HingeSensorAngleProvider
|
import com.android.systemui.unfold.updates.hinge.HingeSensorAngleProvider
|
||||||
@@ -62,7 +63,7 @@ fun createUnfoldTransitionProgressProvider(
|
|||||||
mainExecutor
|
mainExecutor
|
||||||
)
|
)
|
||||||
|
|
||||||
return if (config.isHingeAngleEnabled) {
|
val unfoldTransitionProgressProvider = if (config.isHingeAngleEnabled) {
|
||||||
PhysicsBasedUnfoldTransitionProgressProvider(
|
PhysicsBasedUnfoldTransitionProgressProvider(
|
||||||
mainHandler,
|
mainHandler,
|
||||||
foldStateProvider
|
foldStateProvider
|
||||||
@@ -70,6 +71,10 @@ fun createUnfoldTransitionProgressProvider(
|
|||||||
} else {
|
} else {
|
||||||
FixedTimingTransitionProgressProvider(foldStateProvider)
|
FixedTimingTransitionProgressProvider(foldStateProvider)
|
||||||
}
|
}
|
||||||
|
return ScaleAwareTransitionProgressProvider(
|
||||||
|
unfoldTransitionProgressProvider,
|
||||||
|
context.contentResolver
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createConfig(context: Context): UnfoldTransitionConfig =
|
fun createConfig(context: Context): UnfoldTransitionConfig =
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package com.android.systemui.unfold.util
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.RemoteException
|
import android.os.RemoteException
|
||||||
import android.util.Log
|
|
||||||
import android.view.IRotationWatcher
|
import android.view.IRotationWatcher
|
||||||
import android.view.IWindowManager
|
import android.view.IWindowManager
|
||||||
import android.view.Surface
|
import android.view.Surface
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package com.android.systemui.unfold.util
|
||||||
|
|
||||||
|
import android.animation.ValueAnimator
|
||||||
|
import android.content.ContentResolver
|
||||||
|
import android.database.ContentObserver
|
||||||
|
import android.provider.Settings
|
||||||
|
import com.android.systemui.unfold.UnfoldTransitionProgressProvider
|
||||||
|
import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
|
||||||
|
|
||||||
|
/** Wraps [UnfoldTransitionProgressProvider] to disable transitions when animations are disabled. */
|
||||||
|
class ScaleAwareTransitionProgressProvider(
|
||||||
|
unfoldTransitionProgressProvider: UnfoldTransitionProgressProvider,
|
||||||
|
private val contentResolver: ContentResolver
|
||||||
|
) : UnfoldTransitionProgressProvider {
|
||||||
|
|
||||||
|
private val scopedUnfoldTransitionProgressProvider =
|
||||||
|
ScopedUnfoldTransitionProgressProvider(unfoldTransitionProgressProvider)
|
||||||
|
|
||||||
|
private val animatorDurationScaleObserver = object : ContentObserver(null) {
|
||||||
|
override fun onChange(selfChange: Boolean) {
|
||||||
|
onAnimatorScaleChanged()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
contentResolver.registerContentObserver(
|
||||||
|
Settings.Global.getUriFor(Settings.Global.ANIMATOR_DURATION_SCALE),
|
||||||
|
/* notifyForDescendants= */ false,
|
||||||
|
animatorDurationScaleObserver)
|
||||||
|
onAnimatorScaleChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onAnimatorScaleChanged() {
|
||||||
|
val animationsEnabled = ValueAnimator.areAnimatorsEnabled()
|
||||||
|
scopedUnfoldTransitionProgressProvider.setReadyToHandleTransition(animationsEnabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun addCallback(listener: TransitionProgressListener) {
|
||||||
|
scopedUnfoldTransitionProgressProvider.addCallback(listener)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun removeCallback(listener: TransitionProgressListener) {
|
||||||
|
scopedUnfoldTransitionProgressProvider.removeCallback(listener)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun destroy() {
|
||||||
|
contentResolver.unregisterContentObserver(animatorDurationScaleObserver)
|
||||||
|
scopedUnfoldTransitionProgressProvider.destroy()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.android.systemui.unfold
|
package com.android.systemui.unfold
|
||||||
|
|
||||||
|
import android.animation.ValueAnimator
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.PixelFormat
|
import android.graphics.PixelFormat
|
||||||
import android.hardware.devicestate.DeviceStateManager
|
import android.hardware.devicestate.DeviceStateManager
|
||||||
@@ -111,7 +112,7 @@ class UnfoldLightRevealOverlayAnimation @Inject constructor(
|
|||||||
Trace.beginSection("UnfoldLightRevealOverlayAnimation#onScreenTurningOn")
|
Trace.beginSection("UnfoldLightRevealOverlayAnimation#onScreenTurningOn")
|
||||||
try {
|
try {
|
||||||
// Add the view only if we are unfolding and this is the first screen on
|
// Add the view only if we are unfolding and this is the first screen on
|
||||||
if (!isFolded && !isUnfoldHandled) {
|
if (!isFolded && !isUnfoldHandled && ValueAnimator.areAnimatorsEnabled()) {
|
||||||
addView(onOverlayReady)
|
addView(onOverlayReady)
|
||||||
isUnfoldHandled = true
|
isUnfoldHandled = true
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -0,0 +1,139 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 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.unfold.util
|
||||||
|
|
||||||
|
import android.animation.ValueAnimator
|
||||||
|
import android.content.ContentResolver
|
||||||
|
import android.database.ContentObserver
|
||||||
|
import android.testing.AndroidTestingRunner
|
||||||
|
import androidx.test.filters.SmallTest
|
||||||
|
import com.android.systemui.SysuiTestCase
|
||||||
|
import com.android.systemui.unfold.UnfoldTransitionProgressProvider
|
||||||
|
import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
|
||||||
|
import com.android.systemui.util.mockito.any
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
import org.mockito.ArgumentCaptor
|
||||||
|
import org.mockito.Mock
|
||||||
|
import org.mockito.Mockito.verify
|
||||||
|
import org.mockito.Mockito.verifyNoMoreInteractions
|
||||||
|
import org.mockito.MockitoAnnotations
|
||||||
|
|
||||||
|
@RunWith(AndroidTestingRunner::class)
|
||||||
|
@SmallTest
|
||||||
|
class ScaleAwareUnfoldProgressProviderTest : SysuiTestCase() {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
lateinit var contentResolver: ContentResolver
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
lateinit var sourceProvider: UnfoldTransitionProgressProvider
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
lateinit var sinkProvider: TransitionProgressListener
|
||||||
|
|
||||||
|
lateinit var progressProvider: ScaleAwareTransitionProgressProvider
|
||||||
|
|
||||||
|
private val sourceProviderListenerCaptor =
|
||||||
|
ArgumentCaptor.forClass(TransitionProgressListener::class.java)
|
||||||
|
|
||||||
|
private val animatorDurationScaleListenerCaptor =
|
||||||
|
ArgumentCaptor.forClass(ContentObserver::class.java)
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this)
|
||||||
|
|
||||||
|
progressProvider = ScaleAwareTransitionProgressProvider(
|
||||||
|
sourceProvider,
|
||||||
|
contentResolver
|
||||||
|
)
|
||||||
|
|
||||||
|
verify(sourceProvider).addCallback(sourceProviderListenerCaptor.capture())
|
||||||
|
verify(contentResolver).registerContentObserver(any(), any(),
|
||||||
|
animatorDurationScaleListenerCaptor.capture())
|
||||||
|
|
||||||
|
progressProvider.addCallback(sinkProvider)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun onTransitionStarted_animationsEnabled_eventReceived() {
|
||||||
|
setAnimationsEnabled(true)
|
||||||
|
|
||||||
|
source.onTransitionStarted()
|
||||||
|
|
||||||
|
verify(sinkProvider).onTransitionStarted()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun onTransitionStarted_animationsNotEnabled_eventNotReceived() {
|
||||||
|
setAnimationsEnabled(false)
|
||||||
|
|
||||||
|
source.onTransitionStarted()
|
||||||
|
|
||||||
|
verifyNoMoreInteractions(sinkProvider)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun onTransitionEnd_animationsEnabled_eventReceived() {
|
||||||
|
setAnimationsEnabled(true)
|
||||||
|
|
||||||
|
source.onTransitionFinished()
|
||||||
|
|
||||||
|
verify(sinkProvider).onTransitionFinished()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun onTransitionEnd_animationsNotEnabled_eventNotReceived() {
|
||||||
|
setAnimationsEnabled(false)
|
||||||
|
|
||||||
|
source.onTransitionFinished()
|
||||||
|
|
||||||
|
verifyNoMoreInteractions(sinkProvider)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun onTransitionProgress_animationsEnabled_eventReceived() {
|
||||||
|
setAnimationsEnabled(true)
|
||||||
|
|
||||||
|
source.onTransitionProgress(42f)
|
||||||
|
|
||||||
|
verify(sinkProvider).onTransitionProgress(42f)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun onTransitionProgress_animationsNotEnabled_eventNotReceived() {
|
||||||
|
setAnimationsEnabled(false)
|
||||||
|
|
||||||
|
source.onTransitionProgress(42f)
|
||||||
|
|
||||||
|
verifyNoMoreInteractions(sinkProvider)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setAnimationsEnabled(enabled: Boolean) {
|
||||||
|
val durationScale = if (enabled) {
|
||||||
|
1f
|
||||||
|
} else {
|
||||||
|
0f
|
||||||
|
}
|
||||||
|
ValueAnimator.setDurationScale(durationScale)
|
||||||
|
animatorDurationScaleListenerCaptor.value.dispatchChange(/* selfChange= */false)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val source: TransitionProgressListener
|
||||||
|
get() = sourceProviderListenerCaptor.value
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user