Loading core/api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -22903,6 +22903,7 @@ package android.media { method public void onCryptoError(@NonNull android.media.MediaCodec, @NonNull android.media.MediaCodec.CryptoException); method public abstract void onError(@NonNull android.media.MediaCodec, @NonNull android.media.MediaCodec.CodecException); method public abstract void onInputBufferAvailable(@NonNull android.media.MediaCodec, int); method @FlaggedApi("android.media.codec.subsession_metrics") public void onMetricsFlushed(@NonNull android.media.MediaCodec, @NonNull android.os.PersistableBundle); method public abstract void onOutputBufferAvailable(@NonNull android.media.MediaCodec, int, @NonNull android.media.MediaCodec.BufferInfo); method @FlaggedApi("com.android.media.codec.flags.large_audio_frame") public void onOutputBuffersAvailable(@NonNull android.media.MediaCodec, int, @NonNull java.util.ArrayDeque<android.media.MediaCodec.BufferInfo>); method public abstract void onOutputFormatChanged(@NonNull android.media.MediaCodec, @NonNull android.media.MediaFormat); core/java/android/permission/flags.aconfig +14 −0 Original line number Diff line number Diff line Loading @@ -386,3 +386,17 @@ flag { description: "This fixed read-only flag is used to enable new ranging permission for all ranging use cases." bug: "370977414" } flag { name: "system_selection_toolbar_enabled" namespace: "permissions" description: "Enables the system selection toolbar feature." bug: "363318732" } flag { name: "use_system_selection_toolbar_in_sysui" namespace: "permissions" description: "Uses the SysUi process to host the SelectionToolbarRenderService." bug: "363318732" } media/java/android/media/MediaCodec.java +51 −3 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package android.media; import static android.media.codec.Flags.FLAG_NULL_OUTPUT_SURFACE; import static android.media.codec.Flags.FLAG_REGION_OF_INTEREST; import static android.media.codec.Flags.FLAG_SUBSESSION_METRICS; import static com.android.media.codec.flags.Flags.FLAG_LARGE_AUDIO_FRAME; Loading Loading @@ -890,7 +891,7 @@ import java.util.function.Supplier; any start codes), and submit it as a <strong>regular</strong> input buffer. <p> You will receive an {@link #INFO_OUTPUT_FORMAT_CHANGED} return value from {@link #dequeueOutputBuffer dequeueOutputBuffer} or a {@link Callback#onOutputBufferAvailable #dequeueOutputBuffer dequeueOutputBuffer} or a {@link Callback#onOutputFormatChanged onOutputFormatChanged} callback just after the picture-size change takes place and before any frames with the new size have been returned. <p class=note> Loading Loading @@ -1835,6 +1836,13 @@ final public class MediaCodec { private static final int CB_CRYPTO_ERROR = 6; private static final int CB_LARGE_FRAME_OUTPUT_AVAILABLE = 7; /** * Callback ID for when the metrics for this codec have been flushed due to * the start of a new subsession. The associated Java Message object will * contain the flushed metrics as a PersistentBundle in the obj field. */ private static final int CB_METRICS_FLUSHED = 8; private class EventHandler extends Handler { private MediaCodec mCodec; Loading Loading @@ -2007,6 +2015,15 @@ final public class MediaCodec { break; } case CB_METRICS_FLUSHED: { if (GetFlag(() -> android.media.codec.Flags.subsessionMetrics())) { mCallback.onMetricsFlushed(mCodec, (PersistableBundle)msg.obj); } break; } default: { break; Loading Loading @@ -4959,13 +4976,23 @@ final public class MediaCodec { /** * Return Metrics data about the current codec instance. * <p> * Call this method after configuration, during execution, or after * the codec has been already stopped. * <p> * Beginning with {@link android.os.Build.VERSION_CODES#B} * this method can be used to get the Metrics data prior to an error. * (e.g. in {@link Callback#onError} or after a method throws * {@link MediaCodec.CodecException}.) Before that, the Metrics data was * cleared on error, resulting in a null return value. * * @return a {@link PersistableBundle} containing the set of attributes and values * available for the media being handled by this instance of MediaCodec * The attributes are descibed in {@link MetricsConstants}. * * Additional vendor-specific fields may also be present in * the return value. * the return value. Returns null if there is no Metrics data. * */ public PersistableBundle getMetrics() { PersistableBundle bundle = native_getMetrics(); Loading Loading @@ -5692,6 +5719,27 @@ final public class MediaCodec { */ public abstract void onOutputFormatChanged( @NonNull MediaCodec codec, @NonNull MediaFormat format); /** * Called when the metrics for this codec have been flushed due to the * start of a new subsession. * <p> * This can happen when the codec is reconfigured after stop(), or * mid-stream e.g. if the video size changes. When this happens, the * metrics for the previous subsession are flushed, and * {@link MediaCodec#getMetrics} will return the metrics for the * new subsession. This happens just before the {@link Callback#onOutputFormatChanged} * event, so this <b>optional</b> callback is provided to be able to * capture the final metrics for the previous subsession. * * @param codec The MediaCodec object. * @param metrics The flushed metrics for this codec. */ @FlaggedApi(FLAG_SUBSESSION_METRICS) public void onMetricsFlushed( @NonNull MediaCodec codec, @NonNull PersistableBundle metrics) { // default implementation ignores this callback. } } private void postEventFromNative( Loading packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorTest.kt +100 −20 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import com.android.systemui.flags.fakeSystemPropertiesHelper import com.android.systemui.keyguard.data.repository.fakeBiometricSettingsRepository import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFaceAuthRepository import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository import com.android.systemui.keyguard.data.repository.fakeTrustRepository import com.android.systemui.keyguard.shared.model.AuthenticationFlags import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus Loading @@ -40,6 +41,8 @@ import com.android.systemui.kosmos.testScope import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest import com.android.systemui.power.domain.interactor.powerInteractor import com.android.systemui.scene.domain.interactor.sceneInteractor import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.testKosmos import com.android.systemui.user.data.model.SelectionStatus import com.android.systemui.user.data.repository.fakeUserRepository Loading @@ -47,6 +50,7 @@ import com.android.systemui.user.domain.interactor.selectedUserInteractor import com.android.systemui.util.settings.fakeSettings import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.map import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.advanceTimeBy import kotlinx.coroutines.test.runCurrent Loading Loading @@ -230,11 +234,7 @@ class DeviceUnlockedInteractorTest : SysuiTestCase() { @Test fun deviceUnlockStatus_isResetToFalse_whenDeviceGoesToSleep() = testScope.runTest { kosmos.fakeSettings.putIntForUser( Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, 0, kosmos.selectedUserInteractor.getSelectedUserId(), ) setLockAfterScreenTimeout(0) kosmos.fakeAuthenticationRepository.powerButtonInstantlyLocks = false val deviceUnlockStatus by collectLastValue(underTest.deviceUnlockStatus) Loading @@ -254,11 +254,7 @@ class DeviceUnlockedInteractorTest : SysuiTestCase() { fun deviceUnlockStatus_isResetToFalse_whenDeviceGoesToSleep_afterDelay() = testScope.runTest { val delay = 5000 kosmos.fakeSettings.putIntForUser( Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, delay, kosmos.selectedUserInteractor.getSelectedUserId(), ) setLockAfterScreenTimeout(delay) kosmos.fakeAuthenticationRepository.powerButtonInstantlyLocks = false val deviceUnlockStatus by collectLastValue(underTest.deviceUnlockStatus) Loading @@ -279,11 +275,7 @@ class DeviceUnlockedInteractorTest : SysuiTestCase() { @Test fun deviceUnlockStatus_isResetToFalse_whenDeviceGoesToSleep_powerButtonLocksInstantly() = testScope.runTest { kosmos.fakeSettings.putIntForUser( Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, 5000, kosmos.selectedUserInteractor.getSelectedUserId(), ) setLockAfterScreenTimeout(5000) kosmos.fakeAuthenticationRepository.powerButtonInstantlyLocks = true val deviceUnlockStatus by collectLastValue(underTest.deviceUnlockStatus) Loading @@ -304,11 +296,7 @@ class DeviceUnlockedInteractorTest : SysuiTestCase() { @Test fun deviceUnlockStatus_becomesUnlocked_whenFingerprintUnlocked_whileDeviceAsleep() = testScope.runTest { kosmos.fakeSettings.putIntForUser( Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, 0, kosmos.selectedUserInteractor.getSelectedUserId(), ) setLockAfterScreenTimeout(0) val deviceUnlockStatus by collectLastValue(underTest.deviceUnlockStatus) assertThat(deviceUnlockStatus?.isUnlocked).isFalse() Loading Loading @@ -517,6 +505,98 @@ class DeviceUnlockedInteractorTest : SysuiTestCase() { .isEqualTo(DeviceEntryRestrictionReason.DeviceNotUnlockedSinceMainlineUpdate) } @Test fun deviceUnlockStatus_locksImmediately_whenDreamStarts_noTimeout() = testScope.runTest { setLockAfterScreenTimeout(0) val isUnlocked by collectLastValue(underTest.deviceUnlockStatus.map { it.isUnlocked }) unlockDevice() startDreaming() assertThat(isUnlocked).isFalse() } @Test fun deviceUnlockStatus_locksWithDelay_afterDreamStarts_withTimeout() = testScope.runTest { val delay = 5000 setLockAfterScreenTimeout(delay) val isUnlocked by collectLastValue(underTest.deviceUnlockStatus.map { it.isUnlocked }) unlockDevice() startDreaming() assertThat(isUnlocked).isTrue() advanceTimeBy(delay - 1L) assertThat(isUnlocked).isTrue() advanceTimeBy(1L) assertThat(isUnlocked).isFalse() } @Test fun deviceUnlockStatus_doesNotLockWithDelay_whenDreamStopsBeforeTimeout() = testScope.runTest { val delay = 5000 setLockAfterScreenTimeout(delay) val isUnlocked by collectLastValue(underTest.deviceUnlockStatus.map { it.isUnlocked }) unlockDevice() startDreaming() assertThat(isUnlocked).isTrue() advanceTimeBy(delay - 1L) assertThat(isUnlocked).isTrue() stopDreaming() assertThat(isUnlocked).isTrue() advanceTimeBy(1L) assertThat(isUnlocked).isTrue() } @Test fun deviceUnlockStatus_doesNotLock_whenDreamStarts_ifNotInteractive() = testScope.runTest { setLockAfterScreenTimeout(0) val isUnlocked by collectLastValue(underTest.deviceUnlockStatus.map { it.isUnlocked }) unlockDevice() startDreaming() assertThat(isUnlocked).isFalse() } private fun TestScope.unlockDevice() { val deviceUnlockStatus by collectLastValue(underTest.deviceUnlockStatus) kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus( SuccessFingerprintAuthenticationStatus(0, true) ) assertThat(deviceUnlockStatus?.isUnlocked).isTrue() kosmos.sceneInteractor.changeScene(Scenes.Gone, "reason") runCurrent() } private fun setLockAfterScreenTimeout(timeoutMs: Int) { kosmos.fakeSettings.putIntForUser( Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, timeoutMs, kosmos.selectedUserInteractor.getSelectedUserId(), ) } private fun TestScope.startDreaming() { kosmos.fakeKeyguardRepository.setDreaming(true) runCurrent() } private fun TestScope.stopDreaming() { kosmos.fakeKeyguardRepository.setDreaming(false) runCurrent() } private fun TestScope.verifyRestrictionReasonsForAuthFlags( vararg authFlagToDeviceEntryRestriction: Pair<Int, DeviceEntryRestrictionReason?> ) { Loading packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java +23 −2 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.systemui.statusbar.notification.collection.coordinator; import static com.android.systemui.flags.SceneContainerFlagParameterizationKt.parameterizeSceneContainerFlag; import static com.google.common.truth.Truth.assertThat; import static junit.framework.Assert.assertFalse; Loading @@ -32,9 +34,9 @@ import static org.mockito.Mockito.when; import static kotlinx.coroutines.flow.StateFlowKt.MutableStateFlow; import android.platform.test.annotations.EnableFlags; import android.platform.test.flag.junit.FlagsParameterization; import android.testing.TestableLooper; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import com.android.compose.animation.scene.ObservableTransitionState; Loading @@ -42,6 +44,7 @@ import com.android.systemui.Flags; import com.android.systemui.SysuiTestCase; import com.android.systemui.communal.shared.model.CommunalScenes; import com.android.systemui.dump.DumpManager; import com.android.systemui.flags.BrokenWithSceneContainer; import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.keyguard.shared.model.KeyguardState; import com.android.systemui.keyguard.shared.model.TransitionState; Loading Loading @@ -78,14 +81,23 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.verification.VerificationMode; import java.util.List; import kotlinx.coroutines.flow.MutableStateFlow; import kotlinx.coroutines.test.TestScope; import platform.test.runner.parameterized.ParameterizedAndroidJunit4; import platform.test.runner.parameterized.Parameters; @SmallTest @RunWith(AndroidJUnit4.class) @RunWith(ParameterizedAndroidJunit4.class) @TestableLooper.RunWithLooper public class VisualStabilityCoordinatorTest extends SysuiTestCase { @Parameters(name = "{0}") public static List<FlagsParameterization> getParams() { return parameterizeSceneContainerFlag(); } private VisualStabilityCoordinator mCoordinator; @Mock private DumpManager mDumpManager; Loading Loading @@ -117,6 +129,11 @@ public class VisualStabilityCoordinatorTest extends SysuiTestCase { private NotificationEntry mEntry; private GroupEntry mGroupEntry; public VisualStabilityCoordinatorTest(FlagsParameterization flags) { super(); mSetFlagsRule.setFlagsParameterization(flags); } @Before public void setUp() { MockitoAnnotations.initMocks(this); Loading Loading @@ -251,6 +268,7 @@ public class VisualStabilityCoordinatorTest extends SysuiTestCase { } @Test @BrokenWithSceneContainer(bugId = 377868472) // mReorderingAllowed is broken with SceneContainer public void testLockscreenPartlyShowing_groupAndSectionChangesNotAllowed() { // GIVEN the panel true expanded and device isn't pulsing setFullyDozed(false); Loading @@ -267,6 +285,7 @@ public class VisualStabilityCoordinatorTest extends SysuiTestCase { } @Test @BrokenWithSceneContainer(bugId = 377868472) // mReorderingAllowed is broken with SceneContainer public void testLockscreenFullyShowing_groupAndSectionChangesNotAllowed() { // GIVEN the panel true expanded and device isn't pulsing setFullyDozed(false); Loading Loading @@ -520,6 +539,7 @@ public class VisualStabilityCoordinatorTest extends SysuiTestCase { @Test @EnableFlags(Flags.FLAG_CHECK_LOCKSCREEN_GONE_TRANSITION) @BrokenWithSceneContainer(bugId = 377868472) // mReorderingAllowed is broken with SceneContainer public void testNotLockscreenInGoneTransition_invalidationCalled() { // GIVEN visual stability is being maintained b/c animation is playing mKosmos.getKeyguardTransitionRepository().sendTransitionStepJava( Loading Loading @@ -589,6 +609,7 @@ public class VisualStabilityCoordinatorTest extends SysuiTestCase { } @Test @BrokenWithSceneContainer(bugId = 377868472) // mReorderingAllowed is broken with SceneContainer public void testCommunalShowingWillNotSuppressReordering() { // GIVEN panel is expanded, communal is showing, and QS is collapsed setPulsing(false); Loading Loading
core/api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -22903,6 +22903,7 @@ package android.media { method public void onCryptoError(@NonNull android.media.MediaCodec, @NonNull android.media.MediaCodec.CryptoException); method public abstract void onError(@NonNull android.media.MediaCodec, @NonNull android.media.MediaCodec.CodecException); method public abstract void onInputBufferAvailable(@NonNull android.media.MediaCodec, int); method @FlaggedApi("android.media.codec.subsession_metrics") public void onMetricsFlushed(@NonNull android.media.MediaCodec, @NonNull android.os.PersistableBundle); method public abstract void onOutputBufferAvailable(@NonNull android.media.MediaCodec, int, @NonNull android.media.MediaCodec.BufferInfo); method @FlaggedApi("com.android.media.codec.flags.large_audio_frame") public void onOutputBuffersAvailable(@NonNull android.media.MediaCodec, int, @NonNull java.util.ArrayDeque<android.media.MediaCodec.BufferInfo>); method public abstract void onOutputFormatChanged(@NonNull android.media.MediaCodec, @NonNull android.media.MediaFormat);
core/java/android/permission/flags.aconfig +14 −0 Original line number Diff line number Diff line Loading @@ -386,3 +386,17 @@ flag { description: "This fixed read-only flag is used to enable new ranging permission for all ranging use cases." bug: "370977414" } flag { name: "system_selection_toolbar_enabled" namespace: "permissions" description: "Enables the system selection toolbar feature." bug: "363318732" } flag { name: "use_system_selection_toolbar_in_sysui" namespace: "permissions" description: "Uses the SysUi process to host the SelectionToolbarRenderService." bug: "363318732" }
media/java/android/media/MediaCodec.java +51 −3 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package android.media; import static android.media.codec.Flags.FLAG_NULL_OUTPUT_SURFACE; import static android.media.codec.Flags.FLAG_REGION_OF_INTEREST; import static android.media.codec.Flags.FLAG_SUBSESSION_METRICS; import static com.android.media.codec.flags.Flags.FLAG_LARGE_AUDIO_FRAME; Loading Loading @@ -890,7 +891,7 @@ import java.util.function.Supplier; any start codes), and submit it as a <strong>regular</strong> input buffer. <p> You will receive an {@link #INFO_OUTPUT_FORMAT_CHANGED} return value from {@link #dequeueOutputBuffer dequeueOutputBuffer} or a {@link Callback#onOutputBufferAvailable #dequeueOutputBuffer dequeueOutputBuffer} or a {@link Callback#onOutputFormatChanged onOutputFormatChanged} callback just after the picture-size change takes place and before any frames with the new size have been returned. <p class=note> Loading Loading @@ -1835,6 +1836,13 @@ final public class MediaCodec { private static final int CB_CRYPTO_ERROR = 6; private static final int CB_LARGE_FRAME_OUTPUT_AVAILABLE = 7; /** * Callback ID for when the metrics for this codec have been flushed due to * the start of a new subsession. The associated Java Message object will * contain the flushed metrics as a PersistentBundle in the obj field. */ private static final int CB_METRICS_FLUSHED = 8; private class EventHandler extends Handler { private MediaCodec mCodec; Loading Loading @@ -2007,6 +2015,15 @@ final public class MediaCodec { break; } case CB_METRICS_FLUSHED: { if (GetFlag(() -> android.media.codec.Flags.subsessionMetrics())) { mCallback.onMetricsFlushed(mCodec, (PersistableBundle)msg.obj); } break; } default: { break; Loading Loading @@ -4959,13 +4976,23 @@ final public class MediaCodec { /** * Return Metrics data about the current codec instance. * <p> * Call this method after configuration, during execution, or after * the codec has been already stopped. * <p> * Beginning with {@link android.os.Build.VERSION_CODES#B} * this method can be used to get the Metrics data prior to an error. * (e.g. in {@link Callback#onError} or after a method throws * {@link MediaCodec.CodecException}.) Before that, the Metrics data was * cleared on error, resulting in a null return value. * * @return a {@link PersistableBundle} containing the set of attributes and values * available for the media being handled by this instance of MediaCodec * The attributes are descibed in {@link MetricsConstants}. * * Additional vendor-specific fields may also be present in * the return value. * the return value. Returns null if there is no Metrics data. * */ public PersistableBundle getMetrics() { PersistableBundle bundle = native_getMetrics(); Loading Loading @@ -5692,6 +5719,27 @@ final public class MediaCodec { */ public abstract void onOutputFormatChanged( @NonNull MediaCodec codec, @NonNull MediaFormat format); /** * Called when the metrics for this codec have been flushed due to the * start of a new subsession. * <p> * This can happen when the codec is reconfigured after stop(), or * mid-stream e.g. if the video size changes. When this happens, the * metrics for the previous subsession are flushed, and * {@link MediaCodec#getMetrics} will return the metrics for the * new subsession. This happens just before the {@link Callback#onOutputFormatChanged} * event, so this <b>optional</b> callback is provided to be able to * capture the final metrics for the previous subsession. * * @param codec The MediaCodec object. * @param metrics The flushed metrics for this codec. */ @FlaggedApi(FLAG_SUBSESSION_METRICS) public void onMetricsFlushed( @NonNull MediaCodec codec, @NonNull PersistableBundle metrics) { // default implementation ignores this callback. } } private void postEventFromNative( Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorTest.kt +100 −20 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import com.android.systemui.flags.fakeSystemPropertiesHelper import com.android.systemui.keyguard.data.repository.fakeBiometricSettingsRepository import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFaceAuthRepository import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository import com.android.systemui.keyguard.data.repository.fakeTrustRepository import com.android.systemui.keyguard.shared.model.AuthenticationFlags import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus Loading @@ -40,6 +41,8 @@ import com.android.systemui.kosmos.testScope import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest import com.android.systemui.power.domain.interactor.powerInteractor import com.android.systemui.scene.domain.interactor.sceneInteractor import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.testKosmos import com.android.systemui.user.data.model.SelectionStatus import com.android.systemui.user.data.repository.fakeUserRepository Loading @@ -47,6 +50,7 @@ import com.android.systemui.user.domain.interactor.selectedUserInteractor import com.android.systemui.util.settings.fakeSettings import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.map import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.advanceTimeBy import kotlinx.coroutines.test.runCurrent Loading Loading @@ -230,11 +234,7 @@ class DeviceUnlockedInteractorTest : SysuiTestCase() { @Test fun deviceUnlockStatus_isResetToFalse_whenDeviceGoesToSleep() = testScope.runTest { kosmos.fakeSettings.putIntForUser( Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, 0, kosmos.selectedUserInteractor.getSelectedUserId(), ) setLockAfterScreenTimeout(0) kosmos.fakeAuthenticationRepository.powerButtonInstantlyLocks = false val deviceUnlockStatus by collectLastValue(underTest.deviceUnlockStatus) Loading @@ -254,11 +254,7 @@ class DeviceUnlockedInteractorTest : SysuiTestCase() { fun deviceUnlockStatus_isResetToFalse_whenDeviceGoesToSleep_afterDelay() = testScope.runTest { val delay = 5000 kosmos.fakeSettings.putIntForUser( Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, delay, kosmos.selectedUserInteractor.getSelectedUserId(), ) setLockAfterScreenTimeout(delay) kosmos.fakeAuthenticationRepository.powerButtonInstantlyLocks = false val deviceUnlockStatus by collectLastValue(underTest.deviceUnlockStatus) Loading @@ -279,11 +275,7 @@ class DeviceUnlockedInteractorTest : SysuiTestCase() { @Test fun deviceUnlockStatus_isResetToFalse_whenDeviceGoesToSleep_powerButtonLocksInstantly() = testScope.runTest { kosmos.fakeSettings.putIntForUser( Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, 5000, kosmos.selectedUserInteractor.getSelectedUserId(), ) setLockAfterScreenTimeout(5000) kosmos.fakeAuthenticationRepository.powerButtonInstantlyLocks = true val deviceUnlockStatus by collectLastValue(underTest.deviceUnlockStatus) Loading @@ -304,11 +296,7 @@ class DeviceUnlockedInteractorTest : SysuiTestCase() { @Test fun deviceUnlockStatus_becomesUnlocked_whenFingerprintUnlocked_whileDeviceAsleep() = testScope.runTest { kosmos.fakeSettings.putIntForUser( Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, 0, kosmos.selectedUserInteractor.getSelectedUserId(), ) setLockAfterScreenTimeout(0) val deviceUnlockStatus by collectLastValue(underTest.deviceUnlockStatus) assertThat(deviceUnlockStatus?.isUnlocked).isFalse() Loading Loading @@ -517,6 +505,98 @@ class DeviceUnlockedInteractorTest : SysuiTestCase() { .isEqualTo(DeviceEntryRestrictionReason.DeviceNotUnlockedSinceMainlineUpdate) } @Test fun deviceUnlockStatus_locksImmediately_whenDreamStarts_noTimeout() = testScope.runTest { setLockAfterScreenTimeout(0) val isUnlocked by collectLastValue(underTest.deviceUnlockStatus.map { it.isUnlocked }) unlockDevice() startDreaming() assertThat(isUnlocked).isFalse() } @Test fun deviceUnlockStatus_locksWithDelay_afterDreamStarts_withTimeout() = testScope.runTest { val delay = 5000 setLockAfterScreenTimeout(delay) val isUnlocked by collectLastValue(underTest.deviceUnlockStatus.map { it.isUnlocked }) unlockDevice() startDreaming() assertThat(isUnlocked).isTrue() advanceTimeBy(delay - 1L) assertThat(isUnlocked).isTrue() advanceTimeBy(1L) assertThat(isUnlocked).isFalse() } @Test fun deviceUnlockStatus_doesNotLockWithDelay_whenDreamStopsBeforeTimeout() = testScope.runTest { val delay = 5000 setLockAfterScreenTimeout(delay) val isUnlocked by collectLastValue(underTest.deviceUnlockStatus.map { it.isUnlocked }) unlockDevice() startDreaming() assertThat(isUnlocked).isTrue() advanceTimeBy(delay - 1L) assertThat(isUnlocked).isTrue() stopDreaming() assertThat(isUnlocked).isTrue() advanceTimeBy(1L) assertThat(isUnlocked).isTrue() } @Test fun deviceUnlockStatus_doesNotLock_whenDreamStarts_ifNotInteractive() = testScope.runTest { setLockAfterScreenTimeout(0) val isUnlocked by collectLastValue(underTest.deviceUnlockStatus.map { it.isUnlocked }) unlockDevice() startDreaming() assertThat(isUnlocked).isFalse() } private fun TestScope.unlockDevice() { val deviceUnlockStatus by collectLastValue(underTest.deviceUnlockStatus) kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus( SuccessFingerprintAuthenticationStatus(0, true) ) assertThat(deviceUnlockStatus?.isUnlocked).isTrue() kosmos.sceneInteractor.changeScene(Scenes.Gone, "reason") runCurrent() } private fun setLockAfterScreenTimeout(timeoutMs: Int) { kosmos.fakeSettings.putIntForUser( Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, timeoutMs, kosmos.selectedUserInteractor.getSelectedUserId(), ) } private fun TestScope.startDreaming() { kosmos.fakeKeyguardRepository.setDreaming(true) runCurrent() } private fun TestScope.stopDreaming() { kosmos.fakeKeyguardRepository.setDreaming(false) runCurrent() } private fun TestScope.verifyRestrictionReasonsForAuthFlags( vararg authFlagToDeviceEntryRestriction: Pair<Int, DeviceEntryRestrictionReason?> ) { Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java +23 −2 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.systemui.statusbar.notification.collection.coordinator; import static com.android.systemui.flags.SceneContainerFlagParameterizationKt.parameterizeSceneContainerFlag; import static com.google.common.truth.Truth.assertThat; import static junit.framework.Assert.assertFalse; Loading @@ -32,9 +34,9 @@ import static org.mockito.Mockito.when; import static kotlinx.coroutines.flow.StateFlowKt.MutableStateFlow; import android.platform.test.annotations.EnableFlags; import android.platform.test.flag.junit.FlagsParameterization; import android.testing.TestableLooper; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import com.android.compose.animation.scene.ObservableTransitionState; Loading @@ -42,6 +44,7 @@ import com.android.systemui.Flags; import com.android.systemui.SysuiTestCase; import com.android.systemui.communal.shared.model.CommunalScenes; import com.android.systemui.dump.DumpManager; import com.android.systemui.flags.BrokenWithSceneContainer; import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.keyguard.shared.model.KeyguardState; import com.android.systemui.keyguard.shared.model.TransitionState; Loading Loading @@ -78,14 +81,23 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.verification.VerificationMode; import java.util.List; import kotlinx.coroutines.flow.MutableStateFlow; import kotlinx.coroutines.test.TestScope; import platform.test.runner.parameterized.ParameterizedAndroidJunit4; import platform.test.runner.parameterized.Parameters; @SmallTest @RunWith(AndroidJUnit4.class) @RunWith(ParameterizedAndroidJunit4.class) @TestableLooper.RunWithLooper public class VisualStabilityCoordinatorTest extends SysuiTestCase { @Parameters(name = "{0}") public static List<FlagsParameterization> getParams() { return parameterizeSceneContainerFlag(); } private VisualStabilityCoordinator mCoordinator; @Mock private DumpManager mDumpManager; Loading Loading @@ -117,6 +129,11 @@ public class VisualStabilityCoordinatorTest extends SysuiTestCase { private NotificationEntry mEntry; private GroupEntry mGroupEntry; public VisualStabilityCoordinatorTest(FlagsParameterization flags) { super(); mSetFlagsRule.setFlagsParameterization(flags); } @Before public void setUp() { MockitoAnnotations.initMocks(this); Loading Loading @@ -251,6 +268,7 @@ public class VisualStabilityCoordinatorTest extends SysuiTestCase { } @Test @BrokenWithSceneContainer(bugId = 377868472) // mReorderingAllowed is broken with SceneContainer public void testLockscreenPartlyShowing_groupAndSectionChangesNotAllowed() { // GIVEN the panel true expanded and device isn't pulsing setFullyDozed(false); Loading @@ -267,6 +285,7 @@ public class VisualStabilityCoordinatorTest extends SysuiTestCase { } @Test @BrokenWithSceneContainer(bugId = 377868472) // mReorderingAllowed is broken with SceneContainer public void testLockscreenFullyShowing_groupAndSectionChangesNotAllowed() { // GIVEN the panel true expanded and device isn't pulsing setFullyDozed(false); Loading Loading @@ -520,6 +539,7 @@ public class VisualStabilityCoordinatorTest extends SysuiTestCase { @Test @EnableFlags(Flags.FLAG_CHECK_LOCKSCREEN_GONE_TRANSITION) @BrokenWithSceneContainer(bugId = 377868472) // mReorderingAllowed is broken with SceneContainer public void testNotLockscreenInGoneTransition_invalidationCalled() { // GIVEN visual stability is being maintained b/c animation is playing mKosmos.getKeyguardTransitionRepository().sendTransitionStepJava( Loading Loading @@ -589,6 +609,7 @@ public class VisualStabilityCoordinatorTest extends SysuiTestCase { } @Test @BrokenWithSceneContainer(bugId = 377868472) // mReorderingAllowed is broken with SceneContainer public void testCommunalShowingWillNotSuppressReordering() { // GIVEN panel is expanded, communal is showing, and QS is collapsed setPulsing(false); Loading