Loading packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java +1 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ public class QuickStepContract { public static final String KEY_EXTRA_SYSUI_PROXY = "extra_sysui_proxy"; public static final String KEY_EXTRA_WINDOW_CORNER_RADIUS = "extra_window_corner_radius"; public static final String KEY_EXTRA_SUPPORTS_WINDOW_CORNERS = "extra_supports_window_corners"; public static final String KEY_EXTRA_UNFOLD_ANIMATION_FORWARDER = "extra_unfold_animation"; // See ISysuiUnlockAnimationController.aidl public static final String KEY_EXTRA_UNLOCK_ANIMATION_CONTROLLER = "unlock_animation"; Loading packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java +18 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,8 @@ import com.android.systemui.unfold.FoldStateLogger; import com.android.systemui.unfold.FoldStateLoggingProvider; import com.android.systemui.unfold.SysUIUnfoldComponent; import com.android.systemui.unfold.UnfoldLatencyTracker; import com.android.systemui.unfold.UnfoldTransitionProgressProvider; import com.android.systemui.unfold.progress.UnfoldTransitionProgressForwarder; import com.android.systemui.unfold.util.NaturalRotationUnfoldProgressProvider; import com.android.wm.shell.TaskViewFactory; import com.android.wm.shell.back.BackAnimation; Loading Loading @@ -137,6 +139,10 @@ public interface SysUIComponent { getUnfoldLatencyTracker().init(); getFoldStateLoggingProvider().ifPresent(FoldStateLoggingProvider::init); getFoldStateLogger().ifPresent(FoldStateLogger::init); getUnfoldTransitionProgressProvider().ifPresent((progressProvider) -> getUnfoldTransitionProgressForwarder().ifPresent((forwarder) -> progressProvider.addCallback(forwarder) )); } /** Loading @@ -163,6 +169,18 @@ public interface SysUIComponent { @SysUISingleton UnfoldLatencyTracker getUnfoldLatencyTracker(); /** * Creates a UnfoldTransitionProgressProvider. */ @SysUISingleton Optional<UnfoldTransitionProgressProvider> getUnfoldTransitionProgressProvider(); /** * Creates a UnfoldTransitionProgressForwarder. */ @SysUISingleton Optional<UnfoldTransitionProgressForwarder> getUnfoldTransitionProgressForwarder(); /** * Creates a FoldStateLoggingProvider. */ Loading packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java +11 −1 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON; import static com.android.internal.accessibility.common.ShortcutConstants.CHOOSER_PACKAGE_NAME; import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SUPPORTS_WINDOW_CORNERS; import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYSUI_PROXY; import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_UNFOLD_ANIMATION_FORWARDER; import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_UNLOCK_ANIMATION_CONTROLLER; import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_WINDOW_CORNER_RADIUS; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BOUNCER_SHOWING; Loading Loading @@ -99,6 +100,7 @@ import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.phone.CentralSurfaces; import com.android.systemui.statusbar.phone.StatusBarWindowCallback; import com.android.systemui.statusbar.policy.CallbackController; import com.android.systemui.unfold.progress.UnfoldTransitionProgressForwarder; import com.android.wm.shell.sysui.ShellInterface; import java.io.PrintWriter; Loading Loading @@ -144,6 +146,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis private final CommandQueue mCommandQueue; private final UserTracker mUserTracker; private final KeyguardUnlockAnimationController mSysuiUnlockAnimationController; private final Optional<UnfoldTransitionProgressForwarder> mUnfoldTransitionProgressForwarder; private final UiEventLogger mUiEventLogger; private final DisplayTracker mDisplayTracker; Loading Loading @@ -415,6 +418,10 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis params.putBoolean(KEY_EXTRA_SUPPORTS_WINDOW_CORNERS, mSupportsRoundedCornersOnWindows); params.putBinder(KEY_EXTRA_UNLOCK_ANIMATION_CONTROLLER, mSysuiUnlockAnimationController.asBinder()); mUnfoldTransitionProgressForwarder.ifPresent( unfoldProgressForwarder -> params.putBinder( KEY_EXTRA_UNFOLD_ANIMATION_FORWARDER, unfoldProgressForwarder.asBinder())); // Add all the interfaces exposed by the shell mShellInterface.createExternalInterfaces(params); Loading Loading @@ -512,7 +519,9 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis DisplayTracker displayTracker, KeyguardUnlockAnimationController sysuiUnlockAnimationController, AssistUtils assistUtils, DumpManager dumpManager) { DumpManager dumpManager, Optional<UnfoldTransitionProgressForwarder> unfoldTransitionProgressForwarder ) { // b/241601880: This component shouldn't be running for a non-primary user if (!Process.myUserHandle().equals(UserHandle.SYSTEM)) { Log.e(TAG_OPS, "Unexpected initialization for non-primary user", new Throwable()); Loading @@ -538,6 +547,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis mSysUiState.addCallback(this::notifySystemUiStateFlags); mUiEventLogger = uiEventLogger; mDisplayTracker = displayTracker; mUnfoldTransitionProgressForwarder = unfoldTransitionProgressForwarder; dumpManager.registerDumpable(getClass().getSimpleName(), this); Loading packages/SystemUI/tests/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProviderTest.kt +7 −109 Original line number Diff line number Diff line Loading @@ -20,17 +20,13 @@ import androidx.test.filters.SmallTest import androidx.test.platform.app.InstrumentationRegistry import com.android.systemui.SysuiTestCase import com.android.systemui.unfold.UnfoldTransitionProgressProvider import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener import com.android.systemui.unfold.updates.FOLD_UPDATE_START_OPENING import com.android.systemui.unfold.updates.FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE import com.android.systemui.unfold.updates.FOLD_UPDATE_FINISH_CLOSED import com.android.systemui.unfold.updates.FOLD_UPDATE_FINISH_FULL_OPEN import com.android.systemui.unfold.updates.FOLD_UPDATE_FINISH_HALF_OPEN import com.android.systemui.unfold.updates.FOLD_UPDATE_START_CLOSING import com.android.systemui.unfold.updates.FOLD_UPDATE_FINISH_CLOSED import com.android.systemui.unfold.updates.FOLD_UPDATE_START_OPENING import com.android.systemui.unfold.updates.FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE import com.android.systemui.unfold.util.TestFoldStateProvider import com.android.systemui.util.leak.ReferenceTestUtils.waitForCondition import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertWithMessage import org.junit.Before import org.junit.Test import org.junit.runner.RunWith Loading @@ -45,9 +41,7 @@ class PhysicsBasedUnfoldTransitionProgressProviderTest : SysuiTestCase() { @Before fun setUp() { progressProvider = PhysicsBasedUnfoldTransitionProgressProvider( foldStateProvider ) progressProvider = PhysicsBasedUnfoldTransitionProgressProvider(foldStateProvider) progressProvider.addCallback(listener) } Loading Loading @@ -79,9 +73,7 @@ class PhysicsBasedUnfoldTransitionProgressProviderTest : SysuiTestCase() { { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_FINISH_FULL_OPEN) }, ) with(listener.ensureTransitionFinished()) { assertHasSingleFinishingEvent() } with(listener.ensureTransitionFinished()) { assertHasSingleFinishingEvent() } } @Test Loading Loading @@ -150,106 +142,12 @@ class PhysicsBasedUnfoldTransitionProgressProviderTest : SysuiTestCase() { { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_FINISH_CLOSED) }, ) with(listener.ensureTransitionFinished()) { assertHasFoldAnimationAtTheEnd() } } private class TestUnfoldProgressListener : TransitionProgressListener { private val recordings: MutableList<UnfoldTransitionRecording> = arrayListOf() private var currentRecording: UnfoldTransitionRecording? = null override fun onTransitionStarted() { assertWithMessage("Trying to start a transition when it is already in progress") .that(currentRecording).isNull() currentRecording = UnfoldTransitionRecording() } override fun onTransitionProgress(progress: Float) { assertWithMessage("Received transition progress event when it's not started") .that(currentRecording).isNotNull() currentRecording!!.addProgress(progress) } override fun onTransitionFinishing() { assertWithMessage("Received transition finishing event when it's not started") .that(currentRecording).isNotNull() currentRecording!!.onFinishing() } override fun onTransitionFinished() { assertWithMessage("Received transition finish event when it's not started") .that(currentRecording).isNotNull() recordings += currentRecording!! currentRecording = null } fun ensureTransitionFinished(): UnfoldTransitionRecording { waitForCondition { recordings.size == 1 } return recordings.first() } class UnfoldTransitionRecording { private val progressHistory: MutableList<Float> = arrayListOf() private var finishingInvocations: Int = 0 fun addProgress(progress: Float) { assertThat(progress).isAtMost(1.0f) assertThat(progress).isAtLeast(0.0f) progressHistory += progress } fun onFinishing() { finishingInvocations++ } fun assertIncreasingProgress() { assertThat(progressHistory.size).isGreaterThan(MIN_ANIMATION_EVENTS) assertThat(progressHistory).isInOrder() } fun assertDecreasingProgress() { assertThat(progressHistory.size).isGreaterThan(MIN_ANIMATION_EVENTS) assertThat(progressHistory).isInOrder(Comparator.reverseOrder<Float>()) } fun assertFinishedWithUnfold() { assertThat(progressHistory).isNotEmpty() assertThat(progressHistory.last()).isEqualTo(1.0f) } fun assertFinishedWithFold() { assertThat(progressHistory).isNotEmpty() assertThat(progressHistory.last()).isEqualTo(0.0f) } fun assertHasFoldAnimationAtTheEnd() { // Check that there are at least a few decreasing events at the end assertThat(progressHistory.size).isGreaterThan(MIN_ANIMATION_EVENTS) assertThat(progressHistory.takeLast(MIN_ANIMATION_EVENTS)) .isInOrder(Comparator.reverseOrder<Float>()) assertThat(progressHistory.last()).isEqualTo(0.0f) } fun assertHasSingleFinishingEvent() { assertWithMessage("onTransitionFinishing callback should be invoked exactly " + "one time").that(finishingInvocations).isEqualTo(1) } } private companion object { private const val MIN_ANIMATION_EVENTS = 5 } with(listener.ensureTransitionFinished()) { assertHasFoldAnimationAtTheEnd() } } private fun runOnMainThreadWithInterval(vararg blocks: () -> Unit, intervalMillis: Long = 60) { blocks.forEach { InstrumentationRegistry.getInstrumentation().runOnMainSync { it() } InstrumentationRegistry.getInstrumentation().runOnMainSync { it() } Thread.sleep(intervalMillis) } } Loading packages/SystemUI/tests/src/com/android/systemui/unfold/progress/RemoteUnfoldTransitionReceiverTest.kt 0 → 100644 +72 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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.progress import android.testing.AndroidTestingRunner import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @RunWith(AndroidTestingRunner::class) @SmallTest class RemoteUnfoldTransitionReceiverTest : SysuiTestCase() { private val progressProvider = RemoteUnfoldTransitionReceiver { it.run() } private val listener = TestUnfoldProgressListener() @Before fun setUp() { progressProvider.addCallback(listener) } @Test fun onTransitionStarted_propagated() { progressProvider.onTransitionStarted() listener.assertStarted() } @Test fun onTransitionProgress_propagated() { progressProvider.onTransitionStarted() progressProvider.onTransitionProgress(0.5f) listener.assertLastProgress(0.5f) } @Test fun onTransitionEnded_propagated() { progressProvider.onTransitionStarted() progressProvider.onTransitionProgress(0.5f) progressProvider.onTransitionFinished() listener.ensureTransitionFinished() } @Test fun onTransitionStarted_afterCallbackRemoved_notPropagated() { progressProvider.removeCallback(listener) progressProvider.onTransitionStarted() listener.assertNotStarted() } } Loading
packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java +1 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ public class QuickStepContract { public static final String KEY_EXTRA_SYSUI_PROXY = "extra_sysui_proxy"; public static final String KEY_EXTRA_WINDOW_CORNER_RADIUS = "extra_window_corner_radius"; public static final String KEY_EXTRA_SUPPORTS_WINDOW_CORNERS = "extra_supports_window_corners"; public static final String KEY_EXTRA_UNFOLD_ANIMATION_FORWARDER = "extra_unfold_animation"; // See ISysuiUnlockAnimationController.aidl public static final String KEY_EXTRA_UNLOCK_ANIMATION_CONTROLLER = "unlock_animation"; Loading
packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java +18 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,8 @@ import com.android.systemui.unfold.FoldStateLogger; import com.android.systemui.unfold.FoldStateLoggingProvider; import com.android.systemui.unfold.SysUIUnfoldComponent; import com.android.systemui.unfold.UnfoldLatencyTracker; import com.android.systemui.unfold.UnfoldTransitionProgressProvider; import com.android.systemui.unfold.progress.UnfoldTransitionProgressForwarder; import com.android.systemui.unfold.util.NaturalRotationUnfoldProgressProvider; import com.android.wm.shell.TaskViewFactory; import com.android.wm.shell.back.BackAnimation; Loading Loading @@ -137,6 +139,10 @@ public interface SysUIComponent { getUnfoldLatencyTracker().init(); getFoldStateLoggingProvider().ifPresent(FoldStateLoggingProvider::init); getFoldStateLogger().ifPresent(FoldStateLogger::init); getUnfoldTransitionProgressProvider().ifPresent((progressProvider) -> getUnfoldTransitionProgressForwarder().ifPresent((forwarder) -> progressProvider.addCallback(forwarder) )); } /** Loading @@ -163,6 +169,18 @@ public interface SysUIComponent { @SysUISingleton UnfoldLatencyTracker getUnfoldLatencyTracker(); /** * Creates a UnfoldTransitionProgressProvider. */ @SysUISingleton Optional<UnfoldTransitionProgressProvider> getUnfoldTransitionProgressProvider(); /** * Creates a UnfoldTransitionProgressForwarder. */ @SysUISingleton Optional<UnfoldTransitionProgressForwarder> getUnfoldTransitionProgressForwarder(); /** * Creates a FoldStateLoggingProvider. */ Loading
packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java +11 −1 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON; import static com.android.internal.accessibility.common.ShortcutConstants.CHOOSER_PACKAGE_NAME; import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SUPPORTS_WINDOW_CORNERS; import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYSUI_PROXY; import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_UNFOLD_ANIMATION_FORWARDER; import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_UNLOCK_ANIMATION_CONTROLLER; import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_WINDOW_CORNER_RADIUS; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BOUNCER_SHOWING; Loading Loading @@ -99,6 +100,7 @@ import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.phone.CentralSurfaces; import com.android.systemui.statusbar.phone.StatusBarWindowCallback; import com.android.systemui.statusbar.policy.CallbackController; import com.android.systemui.unfold.progress.UnfoldTransitionProgressForwarder; import com.android.wm.shell.sysui.ShellInterface; import java.io.PrintWriter; Loading Loading @@ -144,6 +146,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis private final CommandQueue mCommandQueue; private final UserTracker mUserTracker; private final KeyguardUnlockAnimationController mSysuiUnlockAnimationController; private final Optional<UnfoldTransitionProgressForwarder> mUnfoldTransitionProgressForwarder; private final UiEventLogger mUiEventLogger; private final DisplayTracker mDisplayTracker; Loading Loading @@ -415,6 +418,10 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis params.putBoolean(KEY_EXTRA_SUPPORTS_WINDOW_CORNERS, mSupportsRoundedCornersOnWindows); params.putBinder(KEY_EXTRA_UNLOCK_ANIMATION_CONTROLLER, mSysuiUnlockAnimationController.asBinder()); mUnfoldTransitionProgressForwarder.ifPresent( unfoldProgressForwarder -> params.putBinder( KEY_EXTRA_UNFOLD_ANIMATION_FORWARDER, unfoldProgressForwarder.asBinder())); // Add all the interfaces exposed by the shell mShellInterface.createExternalInterfaces(params); Loading Loading @@ -512,7 +519,9 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis DisplayTracker displayTracker, KeyguardUnlockAnimationController sysuiUnlockAnimationController, AssistUtils assistUtils, DumpManager dumpManager) { DumpManager dumpManager, Optional<UnfoldTransitionProgressForwarder> unfoldTransitionProgressForwarder ) { // b/241601880: This component shouldn't be running for a non-primary user if (!Process.myUserHandle().equals(UserHandle.SYSTEM)) { Log.e(TAG_OPS, "Unexpected initialization for non-primary user", new Throwable()); Loading @@ -538,6 +547,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis mSysUiState.addCallback(this::notifySystemUiStateFlags); mUiEventLogger = uiEventLogger; mDisplayTracker = displayTracker; mUnfoldTransitionProgressForwarder = unfoldTransitionProgressForwarder; dumpManager.registerDumpable(getClass().getSimpleName(), this); Loading
packages/SystemUI/tests/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProviderTest.kt +7 −109 Original line number Diff line number Diff line Loading @@ -20,17 +20,13 @@ import androidx.test.filters.SmallTest import androidx.test.platform.app.InstrumentationRegistry import com.android.systemui.SysuiTestCase import com.android.systemui.unfold.UnfoldTransitionProgressProvider import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener import com.android.systemui.unfold.updates.FOLD_UPDATE_START_OPENING import com.android.systemui.unfold.updates.FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE import com.android.systemui.unfold.updates.FOLD_UPDATE_FINISH_CLOSED import com.android.systemui.unfold.updates.FOLD_UPDATE_FINISH_FULL_OPEN import com.android.systemui.unfold.updates.FOLD_UPDATE_FINISH_HALF_OPEN import com.android.systemui.unfold.updates.FOLD_UPDATE_START_CLOSING import com.android.systemui.unfold.updates.FOLD_UPDATE_FINISH_CLOSED import com.android.systemui.unfold.updates.FOLD_UPDATE_START_OPENING import com.android.systemui.unfold.updates.FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE import com.android.systemui.unfold.util.TestFoldStateProvider import com.android.systemui.util.leak.ReferenceTestUtils.waitForCondition import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertWithMessage import org.junit.Before import org.junit.Test import org.junit.runner.RunWith Loading @@ -45,9 +41,7 @@ class PhysicsBasedUnfoldTransitionProgressProviderTest : SysuiTestCase() { @Before fun setUp() { progressProvider = PhysicsBasedUnfoldTransitionProgressProvider( foldStateProvider ) progressProvider = PhysicsBasedUnfoldTransitionProgressProvider(foldStateProvider) progressProvider.addCallback(listener) } Loading Loading @@ -79,9 +73,7 @@ class PhysicsBasedUnfoldTransitionProgressProviderTest : SysuiTestCase() { { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_FINISH_FULL_OPEN) }, ) with(listener.ensureTransitionFinished()) { assertHasSingleFinishingEvent() } with(listener.ensureTransitionFinished()) { assertHasSingleFinishingEvent() } } @Test Loading Loading @@ -150,106 +142,12 @@ class PhysicsBasedUnfoldTransitionProgressProviderTest : SysuiTestCase() { { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_FINISH_CLOSED) }, ) with(listener.ensureTransitionFinished()) { assertHasFoldAnimationAtTheEnd() } } private class TestUnfoldProgressListener : TransitionProgressListener { private val recordings: MutableList<UnfoldTransitionRecording> = arrayListOf() private var currentRecording: UnfoldTransitionRecording? = null override fun onTransitionStarted() { assertWithMessage("Trying to start a transition when it is already in progress") .that(currentRecording).isNull() currentRecording = UnfoldTransitionRecording() } override fun onTransitionProgress(progress: Float) { assertWithMessage("Received transition progress event when it's not started") .that(currentRecording).isNotNull() currentRecording!!.addProgress(progress) } override fun onTransitionFinishing() { assertWithMessage("Received transition finishing event when it's not started") .that(currentRecording).isNotNull() currentRecording!!.onFinishing() } override fun onTransitionFinished() { assertWithMessage("Received transition finish event when it's not started") .that(currentRecording).isNotNull() recordings += currentRecording!! currentRecording = null } fun ensureTransitionFinished(): UnfoldTransitionRecording { waitForCondition { recordings.size == 1 } return recordings.first() } class UnfoldTransitionRecording { private val progressHistory: MutableList<Float> = arrayListOf() private var finishingInvocations: Int = 0 fun addProgress(progress: Float) { assertThat(progress).isAtMost(1.0f) assertThat(progress).isAtLeast(0.0f) progressHistory += progress } fun onFinishing() { finishingInvocations++ } fun assertIncreasingProgress() { assertThat(progressHistory.size).isGreaterThan(MIN_ANIMATION_EVENTS) assertThat(progressHistory).isInOrder() } fun assertDecreasingProgress() { assertThat(progressHistory.size).isGreaterThan(MIN_ANIMATION_EVENTS) assertThat(progressHistory).isInOrder(Comparator.reverseOrder<Float>()) } fun assertFinishedWithUnfold() { assertThat(progressHistory).isNotEmpty() assertThat(progressHistory.last()).isEqualTo(1.0f) } fun assertFinishedWithFold() { assertThat(progressHistory).isNotEmpty() assertThat(progressHistory.last()).isEqualTo(0.0f) } fun assertHasFoldAnimationAtTheEnd() { // Check that there are at least a few decreasing events at the end assertThat(progressHistory.size).isGreaterThan(MIN_ANIMATION_EVENTS) assertThat(progressHistory.takeLast(MIN_ANIMATION_EVENTS)) .isInOrder(Comparator.reverseOrder<Float>()) assertThat(progressHistory.last()).isEqualTo(0.0f) } fun assertHasSingleFinishingEvent() { assertWithMessage("onTransitionFinishing callback should be invoked exactly " + "one time").that(finishingInvocations).isEqualTo(1) } } private companion object { private const val MIN_ANIMATION_EVENTS = 5 } with(listener.ensureTransitionFinished()) { assertHasFoldAnimationAtTheEnd() } } private fun runOnMainThreadWithInterval(vararg blocks: () -> Unit, intervalMillis: Long = 60) { blocks.forEach { InstrumentationRegistry.getInstrumentation().runOnMainSync { it() } InstrumentationRegistry.getInstrumentation().runOnMainSync { it() } Thread.sleep(intervalMillis) } } Loading
packages/SystemUI/tests/src/com/android/systemui/unfold/progress/RemoteUnfoldTransitionReceiverTest.kt 0 → 100644 +72 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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.progress import android.testing.AndroidTestingRunner import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @RunWith(AndroidTestingRunner::class) @SmallTest class RemoteUnfoldTransitionReceiverTest : SysuiTestCase() { private val progressProvider = RemoteUnfoldTransitionReceiver { it.run() } private val listener = TestUnfoldProgressListener() @Before fun setUp() { progressProvider.addCallback(listener) } @Test fun onTransitionStarted_propagated() { progressProvider.onTransitionStarted() listener.assertStarted() } @Test fun onTransitionProgress_propagated() { progressProvider.onTransitionStarted() progressProvider.onTransitionProgress(0.5f) listener.assertLastProgress(0.5f) } @Test fun onTransitionEnded_propagated() { progressProvider.onTransitionStarted() progressProvider.onTransitionProgress(0.5f) progressProvider.onTransitionFinished() listener.ensureTransitionFinished() } @Test fun onTransitionStarted_afterCallbackRemoved_notPropagated() { progressProvider.removeCallback(listener) progressProvider.onTransitionStarted() listener.assertNotStarted() } }