From 540f52499b7e96e3cb38aaf5ca4e2098e57740d3 Mon Sep 17 00:00:00 2001 From: Steve Elliott Date: Tue, 4 Apr 2023 20:55:06 -0400 Subject: [PATCH] Remove StatusBarStateListener from NotifShelf This decouples the shelf View from the status bar state, and refactors the exposed API to better capture the View domain. Bug: 271161129 Test: atest SystemUITests Change-Id: Iae05381b7db91339170e1b88ad81395b3c2bcbf2 --- .../systemui/statusbar/NotificationShelf.java | 18 ++++++++++++++- .../interactor/NotificationShelfInteractor.kt | 4 ++++ .../viewbinder/NotificationShelfViewBinder.kt | 23 ++----------------- .../viewmodel/NotificationShelfViewModel.kt | 4 ++++ .../NotificationShelfInteractorTest.kt | 19 ++++++++++++++- .../NotificationShelfViewModelTest.kt | 18 +++++++++++++++ 6 files changed, 63 insertions(+), 23 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java index d1c6aef7b3061..49c8a9003284c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java @@ -99,6 +99,7 @@ public class NotificationShelf extends ActivatableNotificationView implements St private boolean mSensitiveRevealAnimEndabled; private boolean mShelfRefactorFlagEnabled; private boolean mCanModifyColorOfNotifications; + private boolean mCanInteract; public NotificationShelf(Context context, AttributeSet attrs) { super(context, attrs); @@ -922,18 +923,27 @@ public class NotificationShelf extends ActivatableNotificationView implements St @Override public void onStateChanged(int newState) { + assertRefactorFlagDisabled(); mStatusBarState = newState; updateInteractiveness(); } private void updateInteractiveness() { - mInteractive = mStatusBarState == StatusBarState.KEYGUARD && mHasItemsInStableShelf; + mInteractive = canInteract() && mHasItemsInStableShelf; setClickable(mInteractive); setFocusable(mInteractive); setImportantForAccessibility(mInteractive ? View.IMPORTANT_FOR_ACCESSIBILITY_YES : View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS); } + private boolean canInteract() { + if (mShelfRefactorFlagEnabled) { + return mCanInteract; + } else { + return mStatusBarState == StatusBarState.KEYGUARD; + } + } + @Override protected boolean isInteractive() { return mInteractive; @@ -995,6 +1005,12 @@ public class NotificationShelf extends ActivatableNotificationView implements St mCanModifyColorOfNotifications = canModifyColorOfNotifications; } + public void setCanInteract(boolean canInteract) { + if (!checkRefactorFlagEnabled()) return; + mCanInteract = canInteract; + updateInteractiveness(); + } + public void setIndexOfFirstViewInShelf(ExpandableView firstViewInShelf) { mIndexOfFirstViewInShelf = mHostLayoutController.indexOfChild(firstViewInShelf); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractor.kt index db550c00b4a19..8ba65f7a1418a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractor.kt @@ -32,6 +32,10 @@ constructor( private val keyguardRepository: KeyguardRepository, private val deviceEntryFaceAuthRepository: DeviceEntryFaceAuthRepository, ) { + /** Is the shelf showing on the keyguard? */ + val isShowingOnKeyguard: Flow + get() = keyguardRepository.isKeyguardShowing + /** Is the system in a state where the shelf is just a static display of notification icons? */ val isShelfStatic: Flow get() = diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewbinder/NotificationShelfViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewbinder/NotificationShelfViewBinder.kt index bd531caccc5d3..7b3d1de622d5d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewbinder/NotificationShelfViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewbinder/NotificationShelfViewBinder.kt @@ -17,7 +17,6 @@ package com.android.systemui.statusbar.notification.shelf.ui.viewbinder import android.view.View -import android.view.View.OnAttachStateChangeListener import android.view.accessibility.AccessibilityManager import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle @@ -29,7 +28,6 @@ import com.android.systemui.plugins.FalsingManager import com.android.systemui.statusbar.LegacyNotificationShelfControllerImpl import com.android.systemui.statusbar.NotificationShelf import com.android.systemui.statusbar.NotificationShelfController -import com.android.systemui.statusbar.SysuiStatusBarStateController import com.android.systemui.statusbar.notification.row.ActivatableNotificationView import com.android.systemui.statusbar.notification.row.ActivatableNotificationViewController import com.android.systemui.statusbar.notification.row.ExpandableOutlineViewController @@ -40,9 +38,9 @@ import com.android.systemui.statusbar.notification.stack.NotificationStackScroll import com.android.systemui.statusbar.phone.NotificationIconContainer import com.android.systemui.statusbar.phone.NotificationTapHelper import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent.CentralSurfacesScope +import javax.inject.Inject import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach -import javax.inject.Inject /** * Controller class for [NotificationShelf]. This implementation serves as a temporary wrapper @@ -61,7 +59,6 @@ constructor( private val a11yManager: AccessibilityManager, private val falsingManager: FalsingManager, private val falsingCollector: FalsingCollector, - private val statusBarStateController: SysuiStatusBarStateController, ) : NotificationShelfController { override val view: NotificationShelf @@ -87,23 +84,6 @@ constructor( falsingCollector, ) .init() - val onAttachStateListener = - object : OnAttachStateChangeListener { - override fun onViewAttachedToWindow(v: View) { - statusBarStateController.addCallback( - shelf, - SysuiStatusBarStateController.RANK_SHELF, - ) - } - - override fun onViewDetachedFromWindow(v: View) { - statusBarStateController.removeCallback(shelf) - } - } - shelf.addOnAttachStateChangeListener(onAttachStateListener) - if (shelf.isAttachedToWindow) { - onAttachStateListener.onViewAttachedToWindow(shelf) - } } override val intrinsicHeight: Int @@ -141,6 +121,7 @@ object NotificationShelfViewBinder { viewModel.canModifyColorOfNotifications .onEach(shelf::setCanModifyColorOfNotifications) .launchIn(this) + viewModel.isClickable.onEach(shelf::setCanInteract).launchIn(this) } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModel.kt index b84834adf122c..5e297c89dd2f7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModel.kt @@ -30,6 +30,10 @@ class NotificationShelfViewModel constructor( private val interactor: NotificationShelfInteractor, ) { + /** Is the shelf allowed to be clickable when it has content? */ + val isClickable: Flow + get() = interactor.isShowingOnKeyguard + /** Is the shelf allowed to modify the color of notifications in the host layout? */ val canModifyColorOfNotifications: Flow get() = interactor.isShelfStatic.map { static -> !static } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractorTest.kt index 14e5f9e63ebeb..2cc375b3d0edd 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractorTest.kt @@ -24,7 +24,6 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFaceAuthRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository -import com.android.systemui.statusbar.notification.shelf.domain.interactor.NotificationShelfInteractor import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest @@ -68,4 +67,22 @@ class NotificationShelfInteractorTest : SysuiTestCase() { assertThat(shelfStatic).isTrue() } + + @Test + fun shelfOnKeyguard_whenKeyguardShowing() = runTest { + val onKeyguard by collectLastValue(underTest.isShowingOnKeyguard) + + keyguardRepository.setKeyguardShowing(true) + + assertThat(onKeyguard).isTrue() + } + + @Test + fun shelfNotOnKeyguard_whenKeyguardNotShowing() = runTest { + val onKeyguard by collectLastValue(underTest.isShowingOnKeyguard) + + keyguardRepository.setKeyguardShowing(false) + + assertThat(onKeyguard).isFalse() + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelTest.kt index 6c5fb8bcff223..439edaf3faaf6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelTest.kt @@ -69,4 +69,22 @@ class NotificationShelfViewModelTest : SysuiTestCase() { assertThat(canModifyNotifColor).isFalse() } + + @Test + fun isClickable_whenKeyguardShowing() = runTest { + val isClickable by collectLastValue(underTest.isClickable) + + keyguardRepository.setKeyguardShowing(true) + + assertThat(isClickable).isTrue() + } + + @Test + fun isNotClickable_whenKeyguardNotShowing() = runTest { + val isClickable by collectLastValue(underTest.isClickable) + + keyguardRepository.setKeyguardShowing(false) + + assertThat(isClickable).isFalse() + } }