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
This commit is contained in:
Steve Elliott
2023-04-04 20:55:06 -04:00
parent 020162792c
commit 540f52499b
6 changed files with 63 additions and 23 deletions

View File

@@ -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);
}

View File

@@ -32,6 +32,10 @@ constructor(
private val keyguardRepository: KeyguardRepository,
private val deviceEntryFaceAuthRepository: DeviceEntryFaceAuthRepository,
) {
/** Is the shelf showing on the keyguard? */
val isShowingOnKeyguard: Flow<Boolean>
get() = keyguardRepository.isKeyguardShowing
/** Is the system in a state where the shelf is just a static display of notification icons? */
val isShelfStatic: Flow<Boolean>
get() =

View File

@@ -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)
}
}
}

View File

@@ -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<Boolean>
get() = interactor.isShowingOnKeyguard
/** Is the shelf allowed to modify the color of notifications in the host layout? */
val canModifyColorOfNotifications: Flow<Boolean>
get() = interactor.isShelfStatic.map { static -> !static }

View File

@@ -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()
}
}

View File

@@ -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()
}
}