Loading packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/RenderStageManagerTest.kt +33 −38 Original line number Diff line number Diff line Loading @@ -28,43 +28,41 @@ import com.android.systemui.statusbar.notification.collection.ShadeListBuilder import com.android.systemui.statusbar.notification.collection.listbuilder.OnAfterRenderEntryListener import com.android.systemui.statusbar.notification.collection.listbuilder.OnAfterRenderGroupListener import com.android.systemui.statusbar.notification.collection.listbuilder.OnAfterRenderListListener import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.withArgCaptor import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock import org.mockito.Mockito.inOrder import org.mockito.Mockito.never import org.mockito.Mockito.spy import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.Mockito.verifyNoMoreInteractions import org.mockito.MockitoAnnotations import org.mockito.kotlin.any import org.mockito.kotlin.argumentCaptor import org.mockito.kotlin.inOrder import org.mockito.kotlin.mock import org.mockito.kotlin.never import org.mockito.kotlin.spy import org.mockito.kotlin.times import org.mockito.kotlin.verify import org.mockito.kotlin.verifyNoMoreInteractions @SmallTest @RunWith(AndroidJUnit4::class) class RenderStageManagerTest : SysuiTestCase() { @Mock private lateinit var shadeListBuilder: ShadeListBuilder @Mock private lateinit var onAfterRenderListListener: OnAfterRenderListListener @Mock private lateinit var onAfterRenderGroupListener: OnAfterRenderGroupListener @Mock private lateinit var onAfterRenderEntryListener: OnAfterRenderEntryListener private val shadeListBuilder: ShadeListBuilder = mock() private val onAfterRenderListListener: OnAfterRenderListListener = mock() private val onAfterRenderGroupListener: OnAfterRenderGroupListener = mock() private val onAfterRenderEntryListener: OnAfterRenderEntryListener = mock() private val spyViewRenderer = spy(FakeNotifViewRenderer()) private lateinit var onRenderListListener: ShadeListBuilder.OnRenderListListener private lateinit var renderStageManager: RenderStageManager private val spyViewRenderer = spy(FakeNotifViewRenderer()) @Before fun setUp() { MockitoAnnotations.initMocks(this) renderStageManager = RenderStageManager() renderStageManager.attach(shadeListBuilder) onRenderListListener = withArgCaptor { verify(shadeListBuilder).setOnRenderListListener(capture()) } val captor = argumentCaptor<ShadeListBuilder.OnRenderListListener>() verify(shadeListBuilder).setOnRenderListListener(captor.capture()) onRenderListListener = captor.lastValue } private fun setUpRenderer() { Loading @@ -89,7 +87,7 @@ class RenderStageManagerTest : SysuiTestCase() { verifyNoMoreInteractions( onAfterRenderListListener, onAfterRenderGroupListener, onAfterRenderEntryListener onAfterRenderEntryListener, ) } Loading Loading @@ -171,7 +169,7 @@ class RenderStageManagerTest : SysuiTestCase() { verifyNoMoreInteractions( onAfterRenderListListener, onAfterRenderGroupListener, onAfterRenderEntryListener onAfterRenderEntryListener, ) } Loading @@ -191,30 +189,27 @@ class RenderStageManagerTest : SysuiTestCase() { verifyNoMoreInteractions( onAfterRenderListListener, onAfterRenderGroupListener, onAfterRenderEntryListener onAfterRenderEntryListener, ) } private fun listWith2Groups8Entries() = listOf( group( notif(1), notif(2), notif(3) ), private fun listWith2Groups8Entries() = listOf( group(notif(1), notif(2), notif(3)), notif(4), group( notif(5), notif(6), notif(7) ), notif(8) group(notif(5), notif(6), notif(7)), notif(8), ) private class FakeNotifViewRenderer : NotifViewRenderer { override fun onRenderList(notifList: List<ListEntry>) {} override fun getStackController(): NotifStackController = mock() override fun getGroupController(group: GroupEntry): NotifGroupController = mock() override fun getRowController(entry: NotificationEntry): NotifRowController = mock() override fun onDispatchComplete() {} } Loading packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt +63 −66 Original line number Diff line number Diff line Loading @@ -32,23 +32,19 @@ import com.android.systemui.statusbar.notification.row.ExpandableView import com.android.systemui.statusbar.notification.shared.NotificationsImprovedHunAnimation import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager import com.android.systemui.statusbar.policy.AvalancheController import com.android.systemui.util.mockito.mock import com.google.common.truth.Expect import com.google.common.truth.Truth.assertThat import junit.framework.Assert.assertEquals import junit.framework.Assert.assertFalse import junit.framework.Assert.assertTrue import kotlinx.coroutines.ExperimentalCoroutinesApi import org.junit.Assume import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mockito.any import org.mockito.Mockito.eq import org.mockito.Mockito.mock import org.mockito.Mockito.verify import org.mockito.Mockito.`when` as whenever import org.mockito.kotlin.any import org.mockito.kotlin.eq import org.mockito.kotlin.mock import org.mockito.kotlin.verify import org.mockito.kotlin.whenever import platform.test.runner.parameterized.ParameterizedAndroidJunit4 import platform.test.runner.parameterized.Parameters Loading Loading @@ -846,7 +842,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { val viewStart = 0f val shelfStart = 1f val expandableView = mock(ExpandableView::class.java) val expandableView = mock<ExpandableView>() whenever(expandableView.isExpandAnimationRunning).thenReturn(false) whenever(expandableView.hasExpandingChild()).thenReturn(false) Loading @@ -854,7 +850,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { expandableViewState.yTranslation = viewStart stackScrollAlgorithm.updateViewWithShelf(expandableView, expandableViewState, shelfStart) assertFalse(expandableViewState.hidden) assertThat(expandableViewState.hidden).isFalse() } @Test Loading @@ -862,7 +858,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { val shelfStart = 0f val viewStart = 1f val expandableView = mock(ExpandableView::class.java) val expandableView = mock<ExpandableView>() whenever(expandableView.isExpandAnimationRunning).thenReturn(false) whenever(expandableView.hasExpandingChild()).thenReturn(false) Loading @@ -870,7 +866,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { expandableViewState.yTranslation = viewStart stackScrollAlgorithm.updateViewWithShelf(expandableView, expandableViewState, shelfStart) assertTrue(expandableViewState.hidden) assertThat(expandableViewState.hidden).isTrue() } @Test Loading @@ -878,7 +874,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { val shelfStart = 0f val viewStart = 1f val expandableView = mock(ExpandableView::class.java) val expandableView = mock<ExpandableView>() whenever(expandableView.isExpandAnimationRunning).thenReturn(true) whenever(expandableView.hasExpandingChild()).thenReturn(true) Loading @@ -886,7 +882,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { expandableViewState.yTranslation = viewStart stackScrollAlgorithm.updateViewWithShelf(expandableView, expandableViewState, shelfStart) assertFalse(expandableViewState.hidden) assertThat(expandableViewState.hidden).isFalse() } @Test Loading @@ -898,12 +894,12 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { expandableViewState, /* isShadeExpanded= */ true, /* mustStayOnScreen= */ true, /* isViewEndVisible= */ true, /* topVisible = */ true, /* viewEnd= */ 0f, /* maxHunY= */ 10f, /* hunMax = */ 10f, ) assertTrue(expandableViewState.headsUpIsVisible) assertThat(expandableViewState.headsUpIsVisible).isTrue() } @Test Loading @@ -915,12 +911,12 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { expandableViewState, /* isShadeExpanded= */ true, /* mustStayOnScreen= */ true, /* isViewEndVisible= */ true, /* topVisible = */ true, /* viewEnd= */ 10f, /* maxHunY= */ 0f, /* hunMax = */ 0f, ) assertFalse(expandableViewState.headsUpIsVisible) assertThat(expandableViewState.headsUpIsVisible).isFalse() } @Test Loading @@ -932,12 +928,12 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { expandableViewState, /* isShadeExpanded= */ false, /* mustStayOnScreen= */ true, /* isViewEndVisible= */ true, /* topVisible = */ true, /* viewEnd= */ 10f, /* maxHunY= */ 1f, /* hunMax = */ 1f, ) assertTrue(expandableViewState.headsUpIsVisible) assertThat(expandableViewState.headsUpIsVisible).isTrue() } @Test Loading @@ -949,12 +945,12 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { expandableViewState, /* isShadeExpanded= */ true, /* mustStayOnScreen= */ false, /* isViewEndVisible= */ true, /* topVisible = */ true, /* viewEnd= */ 10f, /* maxHunY= */ 1f, /* hunMax = */ 1f, ) assertTrue(expandableViewState.headsUpIsVisible) assertThat(expandableViewState.headsUpIsVisible).isTrue() } @Test Loading @@ -966,12 +962,12 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { expandableViewState, /* isShadeExpanded= */ true, /* mustStayOnScreen= */ true, /* isViewEndVisible= */ false, /* topVisible = */ false, /* viewEnd= */ 10f, /* maxHunY= */ 1f, /* hunMax = */ 1f, ) assertTrue(expandableViewState.headsUpIsVisible) assertThat(expandableViewState.headsUpIsVisible).isTrue() } @Test Loading @@ -986,7 +982,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { ) // qqs (10 + 0) < viewY (50) assertEquals(50f, expandableViewState.yTranslation) assertThat(expandableViewState.yTranslation).isEqualTo(50f) } @Test Loading @@ -1001,7 +997,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { ) // qqs (10 + 0) > viewY (-10) assertEquals(10f, expandableViewState.yTranslation) assertThat(expandableViewState.yTranslation).isEqualTo(10f) } @Test Loading @@ -1019,7 +1015,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { // newTranslation = max(10, -100) = 10 // distToRealY = 10 - (-100f) = 110 // height = max(20 - 110, 10f) assertEquals(10, expandableViewState.height) assertThat(expandableViewState.height).isEqualTo(10) } @Test Loading @@ -1037,7 +1033,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { // newTranslation = max(10, 5) = 10 // distToRealY = 10 - 5 = 5 // height = max(20 - 5, 10) = 15 assertEquals(15, expandableViewState.height) assertThat(expandableViewState.height).isEqualTo(15) } @Test Loading @@ -1047,9 +1043,9 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { /* hostViewHeight= */ 100f, /* stackY= */ 110f, /* viewMaxHeight= */ 20f, /* originalCornerRoundness= */ 0f, /* originalCornerRadius = */ 0f, ) assertEquals(1f, currentRoundness) assertThat(currentRoundness).isEqualTo(1f) } @Test Loading @@ -1059,9 +1055,9 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { /* hostViewHeight= */ 100f, /* stackY= */ 90f, /* viewMaxHeight= */ 20f, /* originalCornerRoundness= */ 0f, /* originalCornerRadius = */ 0f, ) assertEquals(0.5f, currentRoundness) assertThat(currentRoundness).isEqualTo(0.5f) } @Test Loading @@ -1071,9 +1067,9 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { /* hostViewHeight= */ 100f, /* stackY= */ 0f, /* viewMaxHeight= */ 20f, /* originalCornerRoundness= */ 0f, /* originalCornerRadius = */ 0f, ) assertEquals(0f, currentRoundness) assertThat(currentRoundness).isZero() } @Test Loading @@ -1083,9 +1079,9 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { /* hostViewHeight= */ 100f, /* stackY= */ 0f, /* viewMaxHeight= */ 20f, /* originalCornerRoundness= */ 1f, /* originalCornerRadius = */ 1f, ) assertEquals(1f, currentRoundness) assertThat(currentRoundness).isEqualTo(1f) } @Test Loading @@ -1105,13 +1101,14 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { stackScrollAlgorithm.updateChildZValue( /* i= */ 0, /* childrenOnTop= */ 0.0f, /* StackScrollAlgorithmState= */ algorithmState, /* algorithmState = */ algorithmState, /* ambientState= */ ambientState, /* shouldElevateHun= */ true, /* isTopHun = */ true, ) // Then: full shadow would be applied assertEquals(px(R.dimen.heads_up_pinned_elevation), childHunView.viewState.zTranslation) assertThat(childHunView.viewState.zTranslation) .isEqualTo(px(R.dimen.heads_up_pinned_elevation)) } @Test Loading @@ -1133,9 +1130,9 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { stackScrollAlgorithm.updateChildZValue( /* i= */ 0, /* childrenOnTop= */ 0.0f, /* StackScrollAlgorithmState= */ algorithmState, /* algorithmState = */ algorithmState, /* ambientState= */ ambientState, /* shouldElevateHun= */ true, /* isTopHun = */ true, ) // Then: HUN should have shadow, but not as full size Loading Loading @@ -1166,13 +1163,13 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { stackScrollAlgorithm.updateChildZValue( /* i= */ 0, /* childrenOnTop= */ 0.0f, /* StackScrollAlgorithmState= */ algorithmState, /* algorithmState = */ algorithmState, /* ambientState= */ ambientState, /* shouldElevateHun= */ true, /* isTopHun = */ true, ) // Then: HUN should not have shadow assertEquals(0f, childHunView.viewState.zTranslation) assertThat(childHunView.viewState.zTranslation).isZero() } @Test Loading @@ -1195,13 +1192,14 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { stackScrollAlgorithm.updateChildZValue( /* i= */ 0, /* childrenOnTop= */ 0.0f, /* StackScrollAlgorithmState= */ algorithmState, /* algorithmState = */ algorithmState, /* ambientState= */ ambientState, /* shouldElevateHun= */ true, /* isTopHun = */ true, ) // Then: HUN should have full shadow assertEquals(px(R.dimen.heads_up_pinned_elevation), childHunView.viewState.zTranslation) assertThat(childHunView.viewState.zTranslation) .isEqualTo(px(R.dimen.heads_up_pinned_elevation)) } @Test Loading @@ -1225,9 +1223,9 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { stackScrollAlgorithm.updateChildZValue( /* i= */ 0, /* childrenOnTop= */ 0.0f, /* StackScrollAlgorithmState= */ algorithmState, /* algorithmState = */ algorithmState, /* ambientState= */ ambientState, /* shouldElevateHun= */ true, /* isTopHun = */ true, ) // Then: HUN should have shadow, but not as full size Loading @@ -1251,7 +1249,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { stackScrollAlgorithm.updatePulsingStates(algorithmState, ambientState) // Then: ambientState.pulsingRow should still be pulsingNotificationView assertTrue(ambientState.isPulsingRow(pulsingNotificationView)) assertThat(ambientState.isPulsingRow(pulsingNotificationView)).isTrue() } @Test Loading @@ -1268,7 +1266,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { stackScrollAlgorithm.updatePulsingStates(algorithmState, ambientState) // Then: ambientState.pulsingRow should record the pulsingNotificationView assertTrue(ambientState.isPulsingRow(pulsingNotificationView)) assertThat(ambientState.isPulsingRow(pulsingNotificationView)).isTrue() } @Test Loading @@ -1287,7 +1285,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { stackScrollAlgorithm.updatePulsingStates(algorithmState, ambientState) // Then: ambientState.pulsingRow should be null assertTrue(ambientState.isPulsingRow(null)) assertThat(ambientState.isPulsingRow(null)).isTrue() } @Test Loading @@ -1310,10 +1308,8 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { stackScrollAlgorithm.resetViewStates(ambientState, 0) // Then: pulsingNotificationView should show at full height assertEquals( stackScrollAlgorithm.getMaxAllowedChildHeight(pulsingNotificationView), pulsingNotificationView.viewState.height, ) assertThat(pulsingNotificationView.viewState.height) .isEqualTo(stackScrollAlgorithm.getMaxAllowedChildHeight(pulsingNotificationView)) // After: reset dozeAmount and expansionFraction ambientState.dozeAmount = 0f Loading Loading @@ -1418,7 +1414,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { yTranslation = ambientState.maxHeadsUpTranslation - height // move it to the max } assertTrue(stackScrollAlgorithm.shouldHunAppearFromBottom(ambientState, viewState)) assertThat(stackScrollAlgorithm.shouldHunAppearFromBottom(ambientState, viewState)).isTrue() } @Test Loading @@ -1431,7 +1427,8 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { ambientState.maxHeadsUpTranslation - height - 1 // move it below the max } assertFalse(stackScrollAlgorithm.shouldHunAppearFromBottom(ambientState, viewState)) assertThat(stackScrollAlgorithm.shouldHunAppearFromBottom(ambientState, viewState)) .isFalse() } // endregion Loading Loading @@ -1579,13 +1576,13 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { } private fun mockExpandableNotificationRow(): ExpandableNotificationRow { return mock(ExpandableNotificationRow::class.java).apply { return mock<ExpandableNotificationRow>().apply { whenever(viewState).thenReturn(ExpandableViewState()) } } private fun mockFooterView(height: Int): FooterView { return mock(FooterView::class.java).apply { return mock<FooterView>().apply { whenever(viewState).thenReturn(FooterViewState()) whenever(intrinsicHeight).thenReturn(height) } Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/DataStoreCoordinator.kt +6 −6 Original line number Diff line number Diff line Loading @@ -27,13 +27,13 @@ import com.android.systemui.statusbar.notification.collection.render.requireSumm import javax.inject.Inject /** * A small coordinator which updates the notif stack (the view layer which holds notifications) * with high-level data after the stack is populated with the final entries. * A small coordinator which updates the notif stack (the view layer which holds notifications) with * high-level data after the stack is populated with the final entries. */ @CoordinatorScope class DataStoreCoordinator @Inject internal constructor( private val notifLiveDataStoreImpl: NotifLiveDataStoreImpl ) : CoreCoordinator { class DataStoreCoordinator @Inject internal constructor(private val notifLiveDataStoreImpl: NotifLiveDataStoreImpl) : CoreCoordinator { override fun attach(pipeline: NotifPipeline) { pipeline.addOnAfterRenderListListener { entries, _ -> onAfterRenderList(entries) } Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt +6 −7 Original line number Diff line number Diff line Loading @@ -43,8 +43,7 @@ internal constructor( private val groupExpansionManagerImpl: GroupExpansionManagerImpl, private val renderListInteractor: RenderNotificationListInteractor, private val activeNotificationsInteractor: ActiveNotificationsInteractor, private val sensitiveNotificationProtectionController: SensitiveNotificationProtectionController, private val sensitiveNotificationProtectionController: SensitiveNotificationProtectionController, ) : Coordinator { override fun attach(pipeline: NotifPipeline) { Loading @@ -52,7 +51,7 @@ internal constructor( groupExpansionManagerImpl.attach(pipeline) } fun onAfterRenderList(entries: List<ListEntry>, controller: NotifStackController) = private fun onAfterRenderList(entries: List<ListEntry>, controller: NotifStackController) = traceSection("StackCoordinator.onAfterRenderList") { val notifStats = calculateNotifStats(entries) if (FooterViewRefactor.isEnabled) { Loading @@ -78,13 +77,13 @@ internal constructor( val isSilent = section.bucket == BUCKET_SILENT // NOTE: NotificationEntry.isClearable will internally check group children to ensure // the group itself definitively clearable. val isClearable = !isSensitiveContentProtectionActive && entry.isClearable && !entry.isSensitive.value val isClearable = !isSensitiveContentProtectionActive && entry.isClearable && !entry.isSensitive.value when { isSilent && isClearable -> hasClearableSilentNotifs = true isSilent && !isClearable -> hasNonClearableSilentNotifs = true !isSilent && isClearable -> hasClearableAlertingNotifs = true !isSilent && !isClearable -> hasNonClearableAlertingNotifs = true else -> hasNonClearableAlertingNotifs = true } } return NotifStats( Loading @@ -92,7 +91,7 @@ internal constructor( hasNonClearableAlertingNotifs = hasNonClearableAlertingNotifs, hasClearableAlertingNotifs = hasClearableAlertingNotifs, hasNonClearableSilentNotifs = hasNonClearableSilentNotifs, hasClearableSilentNotifs = hasClearableSilentNotifs hasClearableSilentNotifs = hasClearableSilentNotifs, ) } } packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifViewRenderer.kt +14 −14 Original line number Diff line number Diff line Loading @@ -21,10 +21,10 @@ import com.android.systemui.statusbar.notification.collection.ListEntry import com.android.systemui.statusbar.notification.collection.NotificationEntry /** * This interface and the interfaces it returns define the main API surface that must be * implemented by the view implementation. The term "render" is used to indicate a handoff * to the view system, whether that be to attach views to the hierarchy or to update independent * view models, data stores, or adapters. * This interface and the interfaces it returns define the main API surface that must be implemented * by the view implementation. The term "render" is used to indicate a handoff to the view system, * whether that be to attach views to the hierarchy or to update independent view models, data * stores, or adapters. */ interface NotifViewRenderer { Loading @@ -37,21 +37,21 @@ interface NotifViewRenderer { fun onRenderList(notifList: List<ListEntry>) /** * Provides an interface for the pipeline to update the overall shade. * This will be called at most once for each time [onRenderList] is called. * Provides an interface for the pipeline to update the overall shade. This will be called at * most once for each time [onRenderList] is called. */ fun getStackController(): NotifStackController /** * Provides an interface for the pipeline to update individual groups. * This will be called at most once for each group in the most recent call to [onRenderList]. * Provides an interface for the pipeline to update individual groups. This will be called at * most once for each group in the most recent call to [onRenderList]. */ fun getGroupController(group: GroupEntry): NotifGroupController /** * Provides an interface for the pipeline to update individual entries. * This will be called at most once for each entry in the most recent call to [onRenderList]. * This includes top level entries, group summaries, and group children. * Provides an interface for the pipeline to update individual entries. This will be called at * most once for each entry in the most recent call to [onRenderList]. This includes top level * entries, group summaries, and group children. */ fun getRowController(entry: NotificationEntry): NotifRowController Loading Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/RenderStageManagerTest.kt +33 −38 Original line number Diff line number Diff line Loading @@ -28,43 +28,41 @@ import com.android.systemui.statusbar.notification.collection.ShadeListBuilder import com.android.systemui.statusbar.notification.collection.listbuilder.OnAfterRenderEntryListener import com.android.systemui.statusbar.notification.collection.listbuilder.OnAfterRenderGroupListener import com.android.systemui.statusbar.notification.collection.listbuilder.OnAfterRenderListListener import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.withArgCaptor import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock import org.mockito.Mockito.inOrder import org.mockito.Mockito.never import org.mockito.Mockito.spy import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.Mockito.verifyNoMoreInteractions import org.mockito.MockitoAnnotations import org.mockito.kotlin.any import org.mockito.kotlin.argumentCaptor import org.mockito.kotlin.inOrder import org.mockito.kotlin.mock import org.mockito.kotlin.never import org.mockito.kotlin.spy import org.mockito.kotlin.times import org.mockito.kotlin.verify import org.mockito.kotlin.verifyNoMoreInteractions @SmallTest @RunWith(AndroidJUnit4::class) class RenderStageManagerTest : SysuiTestCase() { @Mock private lateinit var shadeListBuilder: ShadeListBuilder @Mock private lateinit var onAfterRenderListListener: OnAfterRenderListListener @Mock private lateinit var onAfterRenderGroupListener: OnAfterRenderGroupListener @Mock private lateinit var onAfterRenderEntryListener: OnAfterRenderEntryListener private val shadeListBuilder: ShadeListBuilder = mock() private val onAfterRenderListListener: OnAfterRenderListListener = mock() private val onAfterRenderGroupListener: OnAfterRenderGroupListener = mock() private val onAfterRenderEntryListener: OnAfterRenderEntryListener = mock() private val spyViewRenderer = spy(FakeNotifViewRenderer()) private lateinit var onRenderListListener: ShadeListBuilder.OnRenderListListener private lateinit var renderStageManager: RenderStageManager private val spyViewRenderer = spy(FakeNotifViewRenderer()) @Before fun setUp() { MockitoAnnotations.initMocks(this) renderStageManager = RenderStageManager() renderStageManager.attach(shadeListBuilder) onRenderListListener = withArgCaptor { verify(shadeListBuilder).setOnRenderListListener(capture()) } val captor = argumentCaptor<ShadeListBuilder.OnRenderListListener>() verify(shadeListBuilder).setOnRenderListListener(captor.capture()) onRenderListListener = captor.lastValue } private fun setUpRenderer() { Loading @@ -89,7 +87,7 @@ class RenderStageManagerTest : SysuiTestCase() { verifyNoMoreInteractions( onAfterRenderListListener, onAfterRenderGroupListener, onAfterRenderEntryListener onAfterRenderEntryListener, ) } Loading Loading @@ -171,7 +169,7 @@ class RenderStageManagerTest : SysuiTestCase() { verifyNoMoreInteractions( onAfterRenderListListener, onAfterRenderGroupListener, onAfterRenderEntryListener onAfterRenderEntryListener, ) } Loading @@ -191,30 +189,27 @@ class RenderStageManagerTest : SysuiTestCase() { verifyNoMoreInteractions( onAfterRenderListListener, onAfterRenderGroupListener, onAfterRenderEntryListener onAfterRenderEntryListener, ) } private fun listWith2Groups8Entries() = listOf( group( notif(1), notif(2), notif(3) ), private fun listWith2Groups8Entries() = listOf( group(notif(1), notif(2), notif(3)), notif(4), group( notif(5), notif(6), notif(7) ), notif(8) group(notif(5), notif(6), notif(7)), notif(8), ) private class FakeNotifViewRenderer : NotifViewRenderer { override fun onRenderList(notifList: List<ListEntry>) {} override fun getStackController(): NotifStackController = mock() override fun getGroupController(group: GroupEntry): NotifGroupController = mock() override fun getRowController(entry: NotificationEntry): NotifRowController = mock() override fun onDispatchComplete() {} } Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt +63 −66 Original line number Diff line number Diff line Loading @@ -32,23 +32,19 @@ import com.android.systemui.statusbar.notification.row.ExpandableView import com.android.systemui.statusbar.notification.shared.NotificationsImprovedHunAnimation import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager import com.android.systemui.statusbar.policy.AvalancheController import com.android.systemui.util.mockito.mock import com.google.common.truth.Expect import com.google.common.truth.Truth.assertThat import junit.framework.Assert.assertEquals import junit.framework.Assert.assertFalse import junit.framework.Assert.assertTrue import kotlinx.coroutines.ExperimentalCoroutinesApi import org.junit.Assume import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mockito.any import org.mockito.Mockito.eq import org.mockito.Mockito.mock import org.mockito.Mockito.verify import org.mockito.Mockito.`when` as whenever import org.mockito.kotlin.any import org.mockito.kotlin.eq import org.mockito.kotlin.mock import org.mockito.kotlin.verify import org.mockito.kotlin.whenever import platform.test.runner.parameterized.ParameterizedAndroidJunit4 import platform.test.runner.parameterized.Parameters Loading Loading @@ -846,7 +842,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { val viewStart = 0f val shelfStart = 1f val expandableView = mock(ExpandableView::class.java) val expandableView = mock<ExpandableView>() whenever(expandableView.isExpandAnimationRunning).thenReturn(false) whenever(expandableView.hasExpandingChild()).thenReturn(false) Loading @@ -854,7 +850,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { expandableViewState.yTranslation = viewStart stackScrollAlgorithm.updateViewWithShelf(expandableView, expandableViewState, shelfStart) assertFalse(expandableViewState.hidden) assertThat(expandableViewState.hidden).isFalse() } @Test Loading @@ -862,7 +858,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { val shelfStart = 0f val viewStart = 1f val expandableView = mock(ExpandableView::class.java) val expandableView = mock<ExpandableView>() whenever(expandableView.isExpandAnimationRunning).thenReturn(false) whenever(expandableView.hasExpandingChild()).thenReturn(false) Loading @@ -870,7 +866,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { expandableViewState.yTranslation = viewStart stackScrollAlgorithm.updateViewWithShelf(expandableView, expandableViewState, shelfStart) assertTrue(expandableViewState.hidden) assertThat(expandableViewState.hidden).isTrue() } @Test Loading @@ -878,7 +874,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { val shelfStart = 0f val viewStart = 1f val expandableView = mock(ExpandableView::class.java) val expandableView = mock<ExpandableView>() whenever(expandableView.isExpandAnimationRunning).thenReturn(true) whenever(expandableView.hasExpandingChild()).thenReturn(true) Loading @@ -886,7 +882,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { expandableViewState.yTranslation = viewStart stackScrollAlgorithm.updateViewWithShelf(expandableView, expandableViewState, shelfStart) assertFalse(expandableViewState.hidden) assertThat(expandableViewState.hidden).isFalse() } @Test Loading @@ -898,12 +894,12 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { expandableViewState, /* isShadeExpanded= */ true, /* mustStayOnScreen= */ true, /* isViewEndVisible= */ true, /* topVisible = */ true, /* viewEnd= */ 0f, /* maxHunY= */ 10f, /* hunMax = */ 10f, ) assertTrue(expandableViewState.headsUpIsVisible) assertThat(expandableViewState.headsUpIsVisible).isTrue() } @Test Loading @@ -915,12 +911,12 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { expandableViewState, /* isShadeExpanded= */ true, /* mustStayOnScreen= */ true, /* isViewEndVisible= */ true, /* topVisible = */ true, /* viewEnd= */ 10f, /* maxHunY= */ 0f, /* hunMax = */ 0f, ) assertFalse(expandableViewState.headsUpIsVisible) assertThat(expandableViewState.headsUpIsVisible).isFalse() } @Test Loading @@ -932,12 +928,12 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { expandableViewState, /* isShadeExpanded= */ false, /* mustStayOnScreen= */ true, /* isViewEndVisible= */ true, /* topVisible = */ true, /* viewEnd= */ 10f, /* maxHunY= */ 1f, /* hunMax = */ 1f, ) assertTrue(expandableViewState.headsUpIsVisible) assertThat(expandableViewState.headsUpIsVisible).isTrue() } @Test Loading @@ -949,12 +945,12 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { expandableViewState, /* isShadeExpanded= */ true, /* mustStayOnScreen= */ false, /* isViewEndVisible= */ true, /* topVisible = */ true, /* viewEnd= */ 10f, /* maxHunY= */ 1f, /* hunMax = */ 1f, ) assertTrue(expandableViewState.headsUpIsVisible) assertThat(expandableViewState.headsUpIsVisible).isTrue() } @Test Loading @@ -966,12 +962,12 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { expandableViewState, /* isShadeExpanded= */ true, /* mustStayOnScreen= */ true, /* isViewEndVisible= */ false, /* topVisible = */ false, /* viewEnd= */ 10f, /* maxHunY= */ 1f, /* hunMax = */ 1f, ) assertTrue(expandableViewState.headsUpIsVisible) assertThat(expandableViewState.headsUpIsVisible).isTrue() } @Test Loading @@ -986,7 +982,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { ) // qqs (10 + 0) < viewY (50) assertEquals(50f, expandableViewState.yTranslation) assertThat(expandableViewState.yTranslation).isEqualTo(50f) } @Test Loading @@ -1001,7 +997,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { ) // qqs (10 + 0) > viewY (-10) assertEquals(10f, expandableViewState.yTranslation) assertThat(expandableViewState.yTranslation).isEqualTo(10f) } @Test Loading @@ -1019,7 +1015,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { // newTranslation = max(10, -100) = 10 // distToRealY = 10 - (-100f) = 110 // height = max(20 - 110, 10f) assertEquals(10, expandableViewState.height) assertThat(expandableViewState.height).isEqualTo(10) } @Test Loading @@ -1037,7 +1033,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { // newTranslation = max(10, 5) = 10 // distToRealY = 10 - 5 = 5 // height = max(20 - 5, 10) = 15 assertEquals(15, expandableViewState.height) assertThat(expandableViewState.height).isEqualTo(15) } @Test Loading @@ -1047,9 +1043,9 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { /* hostViewHeight= */ 100f, /* stackY= */ 110f, /* viewMaxHeight= */ 20f, /* originalCornerRoundness= */ 0f, /* originalCornerRadius = */ 0f, ) assertEquals(1f, currentRoundness) assertThat(currentRoundness).isEqualTo(1f) } @Test Loading @@ -1059,9 +1055,9 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { /* hostViewHeight= */ 100f, /* stackY= */ 90f, /* viewMaxHeight= */ 20f, /* originalCornerRoundness= */ 0f, /* originalCornerRadius = */ 0f, ) assertEquals(0.5f, currentRoundness) assertThat(currentRoundness).isEqualTo(0.5f) } @Test Loading @@ -1071,9 +1067,9 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { /* hostViewHeight= */ 100f, /* stackY= */ 0f, /* viewMaxHeight= */ 20f, /* originalCornerRoundness= */ 0f, /* originalCornerRadius = */ 0f, ) assertEquals(0f, currentRoundness) assertThat(currentRoundness).isZero() } @Test Loading @@ -1083,9 +1079,9 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { /* hostViewHeight= */ 100f, /* stackY= */ 0f, /* viewMaxHeight= */ 20f, /* originalCornerRoundness= */ 1f, /* originalCornerRadius = */ 1f, ) assertEquals(1f, currentRoundness) assertThat(currentRoundness).isEqualTo(1f) } @Test Loading @@ -1105,13 +1101,14 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { stackScrollAlgorithm.updateChildZValue( /* i= */ 0, /* childrenOnTop= */ 0.0f, /* StackScrollAlgorithmState= */ algorithmState, /* algorithmState = */ algorithmState, /* ambientState= */ ambientState, /* shouldElevateHun= */ true, /* isTopHun = */ true, ) // Then: full shadow would be applied assertEquals(px(R.dimen.heads_up_pinned_elevation), childHunView.viewState.zTranslation) assertThat(childHunView.viewState.zTranslation) .isEqualTo(px(R.dimen.heads_up_pinned_elevation)) } @Test Loading @@ -1133,9 +1130,9 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { stackScrollAlgorithm.updateChildZValue( /* i= */ 0, /* childrenOnTop= */ 0.0f, /* StackScrollAlgorithmState= */ algorithmState, /* algorithmState = */ algorithmState, /* ambientState= */ ambientState, /* shouldElevateHun= */ true, /* isTopHun = */ true, ) // Then: HUN should have shadow, but not as full size Loading Loading @@ -1166,13 +1163,13 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { stackScrollAlgorithm.updateChildZValue( /* i= */ 0, /* childrenOnTop= */ 0.0f, /* StackScrollAlgorithmState= */ algorithmState, /* algorithmState = */ algorithmState, /* ambientState= */ ambientState, /* shouldElevateHun= */ true, /* isTopHun = */ true, ) // Then: HUN should not have shadow assertEquals(0f, childHunView.viewState.zTranslation) assertThat(childHunView.viewState.zTranslation).isZero() } @Test Loading @@ -1195,13 +1192,14 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { stackScrollAlgorithm.updateChildZValue( /* i= */ 0, /* childrenOnTop= */ 0.0f, /* StackScrollAlgorithmState= */ algorithmState, /* algorithmState = */ algorithmState, /* ambientState= */ ambientState, /* shouldElevateHun= */ true, /* isTopHun = */ true, ) // Then: HUN should have full shadow assertEquals(px(R.dimen.heads_up_pinned_elevation), childHunView.viewState.zTranslation) assertThat(childHunView.viewState.zTranslation) .isEqualTo(px(R.dimen.heads_up_pinned_elevation)) } @Test Loading @@ -1225,9 +1223,9 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { stackScrollAlgorithm.updateChildZValue( /* i= */ 0, /* childrenOnTop= */ 0.0f, /* StackScrollAlgorithmState= */ algorithmState, /* algorithmState = */ algorithmState, /* ambientState= */ ambientState, /* shouldElevateHun= */ true, /* isTopHun = */ true, ) // Then: HUN should have shadow, but not as full size Loading @@ -1251,7 +1249,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { stackScrollAlgorithm.updatePulsingStates(algorithmState, ambientState) // Then: ambientState.pulsingRow should still be pulsingNotificationView assertTrue(ambientState.isPulsingRow(pulsingNotificationView)) assertThat(ambientState.isPulsingRow(pulsingNotificationView)).isTrue() } @Test Loading @@ -1268,7 +1266,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { stackScrollAlgorithm.updatePulsingStates(algorithmState, ambientState) // Then: ambientState.pulsingRow should record the pulsingNotificationView assertTrue(ambientState.isPulsingRow(pulsingNotificationView)) assertThat(ambientState.isPulsingRow(pulsingNotificationView)).isTrue() } @Test Loading @@ -1287,7 +1285,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { stackScrollAlgorithm.updatePulsingStates(algorithmState, ambientState) // Then: ambientState.pulsingRow should be null assertTrue(ambientState.isPulsingRow(null)) assertThat(ambientState.isPulsingRow(null)).isTrue() } @Test Loading @@ -1310,10 +1308,8 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { stackScrollAlgorithm.resetViewStates(ambientState, 0) // Then: pulsingNotificationView should show at full height assertEquals( stackScrollAlgorithm.getMaxAllowedChildHeight(pulsingNotificationView), pulsingNotificationView.viewState.height, ) assertThat(pulsingNotificationView.viewState.height) .isEqualTo(stackScrollAlgorithm.getMaxAllowedChildHeight(pulsingNotificationView)) // After: reset dozeAmount and expansionFraction ambientState.dozeAmount = 0f Loading Loading @@ -1418,7 +1414,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { yTranslation = ambientState.maxHeadsUpTranslation - height // move it to the max } assertTrue(stackScrollAlgorithm.shouldHunAppearFromBottom(ambientState, viewState)) assertThat(stackScrollAlgorithm.shouldHunAppearFromBottom(ambientState, viewState)).isTrue() } @Test Loading @@ -1431,7 +1427,8 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { ambientState.maxHeadsUpTranslation - height - 1 // move it below the max } assertFalse(stackScrollAlgorithm.shouldHunAppearFromBottom(ambientState, viewState)) assertThat(stackScrollAlgorithm.shouldHunAppearFromBottom(ambientState, viewState)) .isFalse() } // endregion Loading Loading @@ -1579,13 +1576,13 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { } private fun mockExpandableNotificationRow(): ExpandableNotificationRow { return mock(ExpandableNotificationRow::class.java).apply { return mock<ExpandableNotificationRow>().apply { whenever(viewState).thenReturn(ExpandableViewState()) } } private fun mockFooterView(height: Int): FooterView { return mock(FooterView::class.java).apply { return mock<FooterView>().apply { whenever(viewState).thenReturn(FooterViewState()) whenever(intrinsicHeight).thenReturn(height) } Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/DataStoreCoordinator.kt +6 −6 Original line number Diff line number Diff line Loading @@ -27,13 +27,13 @@ import com.android.systemui.statusbar.notification.collection.render.requireSumm import javax.inject.Inject /** * A small coordinator which updates the notif stack (the view layer which holds notifications) * with high-level data after the stack is populated with the final entries. * A small coordinator which updates the notif stack (the view layer which holds notifications) with * high-level data after the stack is populated with the final entries. */ @CoordinatorScope class DataStoreCoordinator @Inject internal constructor( private val notifLiveDataStoreImpl: NotifLiveDataStoreImpl ) : CoreCoordinator { class DataStoreCoordinator @Inject internal constructor(private val notifLiveDataStoreImpl: NotifLiveDataStoreImpl) : CoreCoordinator { override fun attach(pipeline: NotifPipeline) { pipeline.addOnAfterRenderListListener { entries, _ -> onAfterRenderList(entries) } Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt +6 −7 Original line number Diff line number Diff line Loading @@ -43,8 +43,7 @@ internal constructor( private val groupExpansionManagerImpl: GroupExpansionManagerImpl, private val renderListInteractor: RenderNotificationListInteractor, private val activeNotificationsInteractor: ActiveNotificationsInteractor, private val sensitiveNotificationProtectionController: SensitiveNotificationProtectionController, private val sensitiveNotificationProtectionController: SensitiveNotificationProtectionController, ) : Coordinator { override fun attach(pipeline: NotifPipeline) { Loading @@ -52,7 +51,7 @@ internal constructor( groupExpansionManagerImpl.attach(pipeline) } fun onAfterRenderList(entries: List<ListEntry>, controller: NotifStackController) = private fun onAfterRenderList(entries: List<ListEntry>, controller: NotifStackController) = traceSection("StackCoordinator.onAfterRenderList") { val notifStats = calculateNotifStats(entries) if (FooterViewRefactor.isEnabled) { Loading @@ -78,13 +77,13 @@ internal constructor( val isSilent = section.bucket == BUCKET_SILENT // NOTE: NotificationEntry.isClearable will internally check group children to ensure // the group itself definitively clearable. val isClearable = !isSensitiveContentProtectionActive && entry.isClearable && !entry.isSensitive.value val isClearable = !isSensitiveContentProtectionActive && entry.isClearable && !entry.isSensitive.value when { isSilent && isClearable -> hasClearableSilentNotifs = true isSilent && !isClearable -> hasNonClearableSilentNotifs = true !isSilent && isClearable -> hasClearableAlertingNotifs = true !isSilent && !isClearable -> hasNonClearableAlertingNotifs = true else -> hasNonClearableAlertingNotifs = true } } return NotifStats( Loading @@ -92,7 +91,7 @@ internal constructor( hasNonClearableAlertingNotifs = hasNonClearableAlertingNotifs, hasClearableAlertingNotifs = hasClearableAlertingNotifs, hasNonClearableSilentNotifs = hasNonClearableSilentNotifs, hasClearableSilentNotifs = hasClearableSilentNotifs hasClearableSilentNotifs = hasClearableSilentNotifs, ) } }
packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifViewRenderer.kt +14 −14 Original line number Diff line number Diff line Loading @@ -21,10 +21,10 @@ import com.android.systemui.statusbar.notification.collection.ListEntry import com.android.systemui.statusbar.notification.collection.NotificationEntry /** * This interface and the interfaces it returns define the main API surface that must be * implemented by the view implementation. The term "render" is used to indicate a handoff * to the view system, whether that be to attach views to the hierarchy or to update independent * view models, data stores, or adapters. * This interface and the interfaces it returns define the main API surface that must be implemented * by the view implementation. The term "render" is used to indicate a handoff to the view system, * whether that be to attach views to the hierarchy or to update independent view models, data * stores, or adapters. */ interface NotifViewRenderer { Loading @@ -37,21 +37,21 @@ interface NotifViewRenderer { fun onRenderList(notifList: List<ListEntry>) /** * Provides an interface for the pipeline to update the overall shade. * This will be called at most once for each time [onRenderList] is called. * Provides an interface for the pipeline to update the overall shade. This will be called at * most once for each time [onRenderList] is called. */ fun getStackController(): NotifStackController /** * Provides an interface for the pipeline to update individual groups. * This will be called at most once for each group in the most recent call to [onRenderList]. * Provides an interface for the pipeline to update individual groups. This will be called at * most once for each group in the most recent call to [onRenderList]. */ fun getGroupController(group: GroupEntry): NotifGroupController /** * Provides an interface for the pipeline to update individual entries. * This will be called at most once for each entry in the most recent call to [onRenderList]. * This includes top level entries, group summaries, and group children. * Provides an interface for the pipeline to update individual entries. This will be called at * most once for each entry in the most recent call to [onRenderList]. This includes top level * entries, group summaries, and group children. */ fun getRowController(entry: NotificationEntry): NotifRowController Loading