Loading packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelTest.kt +50 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ import android.os.PowerManager import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.flags.EnableSceneContainer import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFaceAuthRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository import com.android.systemui.kosmos.Kosmos Loading @@ -28,9 +30,13 @@ import com.android.systemui.kosmos.runTest import com.android.systemui.kosmos.testCase import com.android.systemui.plugins.statusbar.statusBarStateController import com.android.systemui.power.data.repository.fakePowerRepository import com.android.systemui.shade.domain.interactor.enableDualShade import com.android.systemui.shade.domain.interactor.enableSingleShade import com.android.systemui.shade.domain.interactor.enableSplitShade import com.android.systemui.statusbar.lockscreenShadeTransitionController import com.android.systemui.statusbar.phone.screenOffAnimationController import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runTest import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.eq Loading Loading @@ -120,4 +126,48 @@ class NotificationShelfViewModelTest : SysuiTestCase() { assertThat(powerRepository.lastWakeReason).isEqualTo(PowerManager.WAKE_REASON_GESTURE) verify(keyguardTransitionController).goToLockedShade(Mockito.isNull(), eq(true)) } @Test @EnableSceneContainer fun isAlignedToEnd_splitShade_true() = kosmos.runTest { val isShelfAlignedToEnd by collectLastValue(underTest.isAlignedToEnd) kosmos.enableSplitShade() assertThat(isShelfAlignedToEnd).isTrue() } @Test @EnableSceneContainer fun isAlignedToEnd_singleShade_false() = kosmos.runTest { val isShelfAlignedToEnd by collectLastValue(underTest.isAlignedToEnd) kosmos.enableSingleShade() assertThat(isShelfAlignedToEnd).isFalse() } @Test @EnableSceneContainer fun isAlignedToEnd_dualShade_wideScreen_false() = kosmos.runTest { val isShelfAlignedToEnd by collectLastValue(underTest.isAlignedToEnd) kosmos.enableDualShade(wideLayout = true) assertThat(isShelfAlignedToEnd).isFalse() } @Test @EnableSceneContainer fun isAlignedToEnd_dualShade_narrowScreen_false() = kosmos.runTest { val isShelfAlignedToEnd by collectLastValue(underTest.isAlignedToEnd) kosmos.enableDualShade(wideLayout = false) assertThat(isShelfAlignedToEnd).isFalse() } } packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java +16 −1 Original line number Diff line number Diff line Loading @@ -93,6 +93,7 @@ public class NotificationShelf extends ActivatableNotificationView { private int mPaddingBetweenElements; private int mNotGoneIndex; private boolean mHasItemsInStableShelf; private boolean mAlignedToEnd; private int mScrollFastThreshold; private boolean mInteractive; private boolean mAnimationsEnabled = true; Loading Loading @@ -412,9 +413,23 @@ public class NotificationShelf extends ActivatableNotificationView { public boolean isAlignedToEnd() { if (!NotificationMinimalism.isEnabled()) { return false; } } else if (SceneContainerFlag.isEnabled()) { return mAlignedToEnd; } else { return mAmbientState.getUseSplitShade(); } } /** @see #isAlignedToEnd() */ public void setAlignedToEnd(boolean alignedToEnd) { if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) { return; } if (mAlignedToEnd != alignedToEnd) { mAlignedToEnd = alignedToEnd; requestLayout(); } } @Override public void updateBackgroundColors() { Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractor.kt +14 −0 Original line number Diff line number Diff line Loading @@ -21,11 +21,14 @@ import com.android.systemui.dagger.SysUISingleton import com.android.systemui.deviceentry.data.repository.DeviceEntryFaceAuthRepository import com.android.systemui.keyguard.data.repository.KeyguardRepository import com.android.systemui.power.domain.interactor.PowerInteractor import com.android.systemui.shade.domain.interactor.ShadeModeInteractor import com.android.systemui.shade.shared.model.ShadeMode import com.android.systemui.statusbar.LockscreenShadeTransitionController import com.android.systemui.statusbar.NotificationShelf import javax.inject.Inject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.map /** Interactor for the [NotificationShelf] */ @SysUISingleton Loading @@ -35,6 +38,7 @@ constructor( private val keyguardRepository: KeyguardRepository, private val deviceEntryFaceAuthRepository: DeviceEntryFaceAuthRepository, private val powerInteractor: PowerInteractor, private val shadeModeInteractor: ShadeModeInteractor, private val keyguardTransitionController: LockscreenShadeTransitionController, ) { /** Is the shelf showing on the keyguard? */ Loading @@ -51,6 +55,16 @@ constructor( isKeyguardShowing && isBypassEnabled } /** Should the shelf be aligned to the end in the current configuration? */ val isAlignedToEnd: Flow<Boolean> get() = shadeModeInteractor.shadeMode.map { shadeMode -> when (shadeMode) { ShadeMode.Split -> true else -> false } } /** Transition keyguard to the locked shade, triggered by the shelf. */ fun goToLockedShadeFromShelf() { powerInteractor.wakeUpIfDozing("SHADE_CLICK", PowerManager.WAKE_REASON_GESTURE) Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewbinder/NotificationShelfViewBinder.kt +7 −1 Original line number Diff line number Diff line Loading @@ -16,15 +16,16 @@ package com.android.systemui.statusbar.notification.shelf.ui.viewbinder import com.android.app.tracing.coroutines.launchTraced as launch import com.android.app.tracing.traceSection import com.android.systemui.plugins.FalsingManager import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.statusbar.NotificationShelf import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerShelfViewBinder import com.android.systemui.statusbar.notification.row.ui.viewbinder.ActivatableNotificationViewBinder import com.android.systemui.statusbar.notification.shelf.ui.viewmodel.NotificationShelfViewModel import kotlinx.coroutines.awaitCancellation import kotlinx.coroutines.coroutineScope import com.android.app.tracing.coroutines.launchTraced as launch /** Binds a [NotificationShelf] to its [view model][NotificationShelfViewModel]. */ object NotificationShelfViewBinder { Loading @@ -41,6 +42,11 @@ object NotificationShelfViewBinder { viewModel.canModifyColorOfNotifications.collect(::setCanModifyColorOfNotifications) } launch { viewModel.isClickable.collect(::setCanInteract) } if (SceneContainerFlag.isEnabled) { launch { viewModel.isAlignedToEnd.collect(::setAlignedToEnd) } } registerViewListenersWhileAttached(shelf, viewModel) } } Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModel.kt +11 −0 Original line number Diff line number Diff line Loading @@ -17,11 +17,13 @@ package com.android.systemui.statusbar.notification.shelf.ui.viewmodel import com.android.systemui.dagger.SysUISingleton import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.statusbar.NotificationShelf import com.android.systemui.statusbar.notification.row.ui.viewmodel.ActivatableNotificationViewModel import com.android.systemui.statusbar.notification.shelf.domain.interactor.NotificationShelfInteractor import javax.inject.Inject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map /** ViewModel for [NotificationShelf]. */ Loading @@ -40,6 +42,15 @@ constructor( val canModifyColorOfNotifications: Flow<Boolean> get() = interactor.isShelfStatic.map { static -> !static } /** Is the shelf aligned to the end in the current configuration? */ val isAlignedToEnd: Flow<Boolean> by lazy { if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) { flowOf(false) } else { interactor.isAlignedToEnd } } /** Notifies that the user has clicked the shelf. */ fun onShelfClicked() { interactor.goToLockedShadeFromShelf() Loading Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelTest.kt +50 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ import android.os.PowerManager import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.flags.EnableSceneContainer import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFaceAuthRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository import com.android.systemui.kosmos.Kosmos Loading @@ -28,9 +30,13 @@ import com.android.systemui.kosmos.runTest import com.android.systemui.kosmos.testCase import com.android.systemui.plugins.statusbar.statusBarStateController import com.android.systemui.power.data.repository.fakePowerRepository import com.android.systemui.shade.domain.interactor.enableDualShade import com.android.systemui.shade.domain.interactor.enableSingleShade import com.android.systemui.shade.domain.interactor.enableSplitShade import com.android.systemui.statusbar.lockscreenShadeTransitionController import com.android.systemui.statusbar.phone.screenOffAnimationController import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runTest import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.eq Loading Loading @@ -120,4 +126,48 @@ class NotificationShelfViewModelTest : SysuiTestCase() { assertThat(powerRepository.lastWakeReason).isEqualTo(PowerManager.WAKE_REASON_GESTURE) verify(keyguardTransitionController).goToLockedShade(Mockito.isNull(), eq(true)) } @Test @EnableSceneContainer fun isAlignedToEnd_splitShade_true() = kosmos.runTest { val isShelfAlignedToEnd by collectLastValue(underTest.isAlignedToEnd) kosmos.enableSplitShade() assertThat(isShelfAlignedToEnd).isTrue() } @Test @EnableSceneContainer fun isAlignedToEnd_singleShade_false() = kosmos.runTest { val isShelfAlignedToEnd by collectLastValue(underTest.isAlignedToEnd) kosmos.enableSingleShade() assertThat(isShelfAlignedToEnd).isFalse() } @Test @EnableSceneContainer fun isAlignedToEnd_dualShade_wideScreen_false() = kosmos.runTest { val isShelfAlignedToEnd by collectLastValue(underTest.isAlignedToEnd) kosmos.enableDualShade(wideLayout = true) assertThat(isShelfAlignedToEnd).isFalse() } @Test @EnableSceneContainer fun isAlignedToEnd_dualShade_narrowScreen_false() = kosmos.runTest { val isShelfAlignedToEnd by collectLastValue(underTest.isAlignedToEnd) kosmos.enableDualShade(wideLayout = false) assertThat(isShelfAlignedToEnd).isFalse() } }
packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java +16 −1 Original line number Diff line number Diff line Loading @@ -93,6 +93,7 @@ public class NotificationShelf extends ActivatableNotificationView { private int mPaddingBetweenElements; private int mNotGoneIndex; private boolean mHasItemsInStableShelf; private boolean mAlignedToEnd; private int mScrollFastThreshold; private boolean mInteractive; private boolean mAnimationsEnabled = true; Loading Loading @@ -412,9 +413,23 @@ public class NotificationShelf extends ActivatableNotificationView { public boolean isAlignedToEnd() { if (!NotificationMinimalism.isEnabled()) { return false; } } else if (SceneContainerFlag.isEnabled()) { return mAlignedToEnd; } else { return mAmbientState.getUseSplitShade(); } } /** @see #isAlignedToEnd() */ public void setAlignedToEnd(boolean alignedToEnd) { if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) { return; } if (mAlignedToEnd != alignedToEnd) { mAlignedToEnd = alignedToEnd; requestLayout(); } } @Override public void updateBackgroundColors() { Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractor.kt +14 −0 Original line number Diff line number Diff line Loading @@ -21,11 +21,14 @@ import com.android.systemui.dagger.SysUISingleton import com.android.systemui.deviceentry.data.repository.DeviceEntryFaceAuthRepository import com.android.systemui.keyguard.data.repository.KeyguardRepository import com.android.systemui.power.domain.interactor.PowerInteractor import com.android.systemui.shade.domain.interactor.ShadeModeInteractor import com.android.systemui.shade.shared.model.ShadeMode import com.android.systemui.statusbar.LockscreenShadeTransitionController import com.android.systemui.statusbar.NotificationShelf import javax.inject.Inject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.map /** Interactor for the [NotificationShelf] */ @SysUISingleton Loading @@ -35,6 +38,7 @@ constructor( private val keyguardRepository: KeyguardRepository, private val deviceEntryFaceAuthRepository: DeviceEntryFaceAuthRepository, private val powerInteractor: PowerInteractor, private val shadeModeInteractor: ShadeModeInteractor, private val keyguardTransitionController: LockscreenShadeTransitionController, ) { /** Is the shelf showing on the keyguard? */ Loading @@ -51,6 +55,16 @@ constructor( isKeyguardShowing && isBypassEnabled } /** Should the shelf be aligned to the end in the current configuration? */ val isAlignedToEnd: Flow<Boolean> get() = shadeModeInteractor.shadeMode.map { shadeMode -> when (shadeMode) { ShadeMode.Split -> true else -> false } } /** Transition keyguard to the locked shade, triggered by the shelf. */ fun goToLockedShadeFromShelf() { powerInteractor.wakeUpIfDozing("SHADE_CLICK", PowerManager.WAKE_REASON_GESTURE) Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewbinder/NotificationShelfViewBinder.kt +7 −1 Original line number Diff line number Diff line Loading @@ -16,15 +16,16 @@ package com.android.systemui.statusbar.notification.shelf.ui.viewbinder import com.android.app.tracing.coroutines.launchTraced as launch import com.android.app.tracing.traceSection import com.android.systemui.plugins.FalsingManager import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.statusbar.NotificationShelf import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerShelfViewBinder import com.android.systemui.statusbar.notification.row.ui.viewbinder.ActivatableNotificationViewBinder import com.android.systemui.statusbar.notification.shelf.ui.viewmodel.NotificationShelfViewModel import kotlinx.coroutines.awaitCancellation import kotlinx.coroutines.coroutineScope import com.android.app.tracing.coroutines.launchTraced as launch /** Binds a [NotificationShelf] to its [view model][NotificationShelfViewModel]. */ object NotificationShelfViewBinder { Loading @@ -41,6 +42,11 @@ object NotificationShelfViewBinder { viewModel.canModifyColorOfNotifications.collect(::setCanModifyColorOfNotifications) } launch { viewModel.isClickable.collect(::setCanInteract) } if (SceneContainerFlag.isEnabled) { launch { viewModel.isAlignedToEnd.collect(::setAlignedToEnd) } } registerViewListenersWhileAttached(shelf, viewModel) } } Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModel.kt +11 −0 Original line number Diff line number Diff line Loading @@ -17,11 +17,13 @@ package com.android.systemui.statusbar.notification.shelf.ui.viewmodel import com.android.systemui.dagger.SysUISingleton import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.statusbar.NotificationShelf import com.android.systemui.statusbar.notification.row.ui.viewmodel.ActivatableNotificationViewModel import com.android.systemui.statusbar.notification.shelf.domain.interactor.NotificationShelfInteractor import javax.inject.Inject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map /** ViewModel for [NotificationShelf]. */ Loading @@ -40,6 +42,15 @@ constructor( val canModifyColorOfNotifications: Flow<Boolean> get() = interactor.isShelfStatic.map { static -> !static } /** Is the shelf aligned to the end in the current configuration? */ val isAlignedToEnd: Flow<Boolean> by lazy { if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) { flowOf(false) } else { interactor.isAlignedToEnd } } /** Notifies that the user has clicked the shelf. */ fun onShelfClicked() { interactor.goToLockedShadeFromShelf() Loading