Loading packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelTest.kt +32 −73 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import com.android.systemui.statusbar.notification.data.repository.UnconfinedFak import com.android.systemui.statusbar.notification.data.repository.activeNotificationListRepository import com.android.systemui.statusbar.notification.headsup.PinnedStatus import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel.When import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel import com.android.systemui.statusbar.notification.stack.data.repository.headsUpNotificationRepository import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernization Loading Loading @@ -295,11 +296,7 @@ class NotifChipsViewModelTest : SysuiTestCase() { val promotedContentBuilder = PromotedNotificationContentModel.Builder("notif").apply { this.shortCriticalText = "Arrived" this.time = PromotedNotificationContentModel.When( time = currentTime + 30.minutes.inWholeMilliseconds, mode = PromotedNotificationContentModel.When.Mode.BasicTime, ) this.time = When.Time(currentTime + 30.minutes.inWholeMilliseconds) } setNotifs( listOf( Loading Loading @@ -351,11 +348,7 @@ class NotifChipsViewModelTest : SysuiTestCase() { val promotedContentBuilder = PromotedNotificationContentModel.Builder("notif").apply { this.wasPromotedAutomatically = true this.time = PromotedNotificationContentModel.When( time = currentTime + 30.minutes.inWholeMilliseconds, mode = PromotedNotificationContentModel.When.Mode.BasicTime, ) this.time = When.Time(currentTime + 30.minutes.inWholeMilliseconds) } setNotifs( listOf( Loading Loading @@ -383,11 +376,7 @@ class NotifChipsViewModelTest : SysuiTestCase() { val promotedContentBuilder = PromotedNotificationContentModel.Builder("notif").apply { this.wasPromotedAutomatically = false this.time = PromotedNotificationContentModel.When( time = currentTime + 30.minutes.inWholeMilliseconds, mode = PromotedNotificationContentModel.When.Mode.BasicTime, ) this.time = When.Time(currentTime + 30.minutes.inWholeMilliseconds) } setNotifs( listOf( Loading @@ -414,11 +403,7 @@ class NotifChipsViewModelTest : SysuiTestCase() { val promotedContentBuilder = PromotedNotificationContentModel.Builder("notif").apply { this.time = PromotedNotificationContentModel.When( time = currentTime + 13.minutes.inWholeMilliseconds, mode = PromotedNotificationContentModel.When.Mode.BasicTime, ) this.time = When.Time(currentTime + 13.minutes.inWholeMilliseconds) } setNotifs( Loading Loading @@ -446,11 +431,7 @@ class NotifChipsViewModelTest : SysuiTestCase() { val promotedContentBuilder = PromotedNotificationContentModel.Builder("notif").apply { this.time = PromotedNotificationContentModel.When( time = currentTime + 500, mode = PromotedNotificationContentModel.When.Mode.BasicTime, ) this.time = When.Time(currentTime + 500) } setNotifs( Loading Loading @@ -478,11 +459,7 @@ class NotifChipsViewModelTest : SysuiTestCase() { val promotedContentBuilder = PromotedNotificationContentModel.Builder("notif").apply { this.time = PromotedNotificationContentModel.When( time = currentTime, mode = PromotedNotificationContentModel.When.Mode.BasicTime, ) this.time = When.Time(currentTime) } setNotifs( Loading Loading @@ -510,11 +487,7 @@ class NotifChipsViewModelTest : SysuiTestCase() { val promotedContentBuilder = PromotedNotificationContentModel.Builder("notif").apply { this.time = PromotedNotificationContentModel.When( time = currentTime - 2.minutes.inWholeMilliseconds, mode = PromotedNotificationContentModel.When.Mode.BasicTime, ) this.time = When.Time(currentTime - 2.minutes.inWholeMilliseconds) } setNotifs( Loading Loading @@ -543,11 +516,7 @@ class NotifChipsViewModelTest : SysuiTestCase() { val promotedContentBuilder = PromotedNotificationContentModel.Builder("notif").apply { this.time = PromotedNotificationContentModel.When( time = currentTime + 3.minutes.inWholeMilliseconds, mode = PromotedNotificationContentModel.When.Mode.BasicTime, ) this.time = When.Time(currentTime + 3.minutes.inWholeMilliseconds) } setNotifs( Loading Loading @@ -579,13 +548,16 @@ class NotifChipsViewModelTest : SysuiTestCase() { val currentTime = 30.minutes.inWholeMilliseconds fakeSystemClock.setCurrentTimeMillis(currentTime) val currentElapsed = currentTime + fakeSystemClock.elapsedRealtime() - fakeSystemClock.currentTimeMillis() val whenElapsed = currentElapsed - 1.minutes.inWholeMilliseconds val promotedContentBuilder = PromotedNotificationContentModel.Builder("notif").apply { this.time = PromotedNotificationContentModel.When( time = currentTime + 10.minutes.inWholeMilliseconds, mode = PromotedNotificationContentModel.When.Mode.CountUp, ) When.Chronometer(elapsedRealtimeMillis = whenElapsed, isCountDown = false) } setNotifs( listOf( Loading @@ -599,6 +571,8 @@ class NotifChipsViewModelTest : SysuiTestCase() { assertThat(latest).hasSize(1) assertThat(latest!![0]).isInstanceOf(OngoingActivityChipModel.Active.Timer::class.java) assertThat((latest!![0] as OngoingActivityChipModel.Active.Timer).startTimeMs) .isEqualTo(whenElapsed) } @Test Loading @@ -609,13 +583,16 @@ class NotifChipsViewModelTest : SysuiTestCase() { val currentTime = 30.minutes.inWholeMilliseconds fakeSystemClock.setCurrentTimeMillis(currentTime) val currentElapsed = currentTime + fakeSystemClock.elapsedRealtime() - fakeSystemClock.currentTimeMillis() val whenElapsed = currentElapsed + 10.minutes.inWholeMilliseconds val promotedContentBuilder = PromotedNotificationContentModel.Builder("notif").apply { this.time = PromotedNotificationContentModel.When( time = currentTime + 10.minutes.inWholeMilliseconds, mode = PromotedNotificationContentModel.When.Mode.CountDown, ) When.Chronometer(elapsedRealtimeMillis = whenElapsed, isCountDown = true) } setNotifs( listOf( Loading @@ -629,6 +606,8 @@ class NotifChipsViewModelTest : SysuiTestCase() { assertThat(latest).hasSize(1) assertThat(latest!![0]).isInstanceOf(OngoingActivityChipModel.Active.Timer::class.java) assertThat((latest!![0] as OngoingActivityChipModel.Active.Timer).startTimeMs) .isEqualTo(whenElapsed) } @Test Loading @@ -641,11 +620,7 @@ class NotifChipsViewModelTest : SysuiTestCase() { val promotedContentBuilder = PromotedNotificationContentModel.Builder("notif").apply { this.time = PromotedNotificationContentModel.When( time = currentTime + 10.minutes.inWholeMilliseconds, mode = PromotedNotificationContentModel.When.Mode.BasicTime, ) this.time = When.Time(currentTime + 10.minutes.inWholeMilliseconds) } setNotifs( listOf( Loading Loading @@ -675,11 +650,7 @@ class NotifChipsViewModelTest : SysuiTestCase() { val promotedContentBuilder = PromotedNotificationContentModel.Builder("notif").apply { this.time = PromotedNotificationContentModel.When( time = currentTime + 10.minutes.inWholeMilliseconds, mode = PromotedNotificationContentModel.When.Mode.BasicTime, ) this.time = When.Time(currentTime + 10.minutes.inWholeMilliseconds) } setNotifs( listOf( Loading Loading @@ -716,19 +687,11 @@ class NotifChipsViewModelTest : SysuiTestCase() { val promotedContentBuilder = PromotedNotificationContentModel.Builder("notif").apply { this.time = PromotedNotificationContentModel.When( time = currentTime + 10.minutes.inWholeMilliseconds, mode = PromotedNotificationContentModel.When.Mode.BasicTime, ) this.time = When.Time(currentTime + 10.minutes.inWholeMilliseconds) } val otherPromotedContentBuilder = PromotedNotificationContentModel.Builder("other notif").apply { this.time = PromotedNotificationContentModel.When( time = currentTime + 10.minutes.inWholeMilliseconds, mode = PromotedNotificationContentModel.When.Mode.BasicTime, ) this.time = When.Time(currentTime + 10.minutes.inWholeMilliseconds) } val icon = createStatusBarIconViewOrNull() val otherIcon = createStatusBarIconViewOrNull() Loading Loading @@ -772,11 +735,7 @@ class NotifChipsViewModelTest : SysuiTestCase() { val promotedContentBuilder = PromotedNotificationContentModel.Builder("notif").apply { this.time = PromotedNotificationContentModel.When( time = currentTime + 10.minutes.inWholeMilliseconds, mode = PromotedNotificationContentModel.When.Mode.BasicTime, ) this.time = When.Time(currentTime + 10.minutes.inWholeMilliseconds) } setNotifs( listOf( Loading packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorImplTest.kt +180 −5 Original line number Diff line number Diff line Loading @@ -39,18 +39,24 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntryB import com.android.systemui.statusbar.notification.promoted.AutomaticPromotionCoordinator.Companion.EXTRA_WAS_AUTOMATICALLY_PROMOTED import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel.Style import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel.When import com.android.systemui.statusbar.notification.row.RowImageInflater import com.android.systemui.testKosmos import com.android.systemui.util.time.fakeSystemClock import com.android.systemui.util.time.systemClock import com.google.common.truth.Truth.assertThat import kotlin.time.Duration import kotlin.time.Duration.Companion.minutes import org.junit.Test import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class PromotedNotificationContentExtractorImplTest : SysuiTestCase() { private val kosmos = testKosmos() private val kosmos = testKosmos().apply { systemClock = fakeSystemClock } private val underTest = kosmos.promotedNotificationContentExtractor private val systemClock = kosmos.fakeSystemClock private val rowImageInflater = RowImageInflater.newInstance(previousIndex = null) private val imageModelProvider by lazy { rowImageInflater.useForContentModel() } Loading Loading @@ -177,7 +183,176 @@ class PromotedNotificationContentExtractorImplTest : SysuiTestCase() { @Test @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME) fun extractsContent_fromBaseStyle() { fun extractTime_none() { assertExtractedTime(hasTime = false, hasChronometer = false, expected = ExpectedTime.Null) } @Test @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME) fun extractTime_basicTimeNow() { assertExtractedTime( hasTime = true, hasChronometer = false, whenOffset = Duration.ZERO, expected = ExpectedTime.Time, ) } @Test @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME) fun extractTime_basicTimePast() { assertExtractedTime( hasTime = true, hasChronometer = false, whenOffset = (-5).minutes, expected = ExpectedTime.Time, ) } @Test @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME) fun extractTime_basicTimeFuture() { assertExtractedTime( hasTime = true, hasChronometer = false, whenOffset = 5.minutes, expected = ExpectedTime.Time, ) } @Test @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME) fun extractTime_countUpNow() { assertExtractedTime( hasTime = false, hasChronometer = true, isCountDown = false, whenOffset = Duration.ZERO, expected = ExpectedTime.CountUp, ) } @Test @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME) fun extractTime_countUpPast() { assertExtractedTime( hasTime = false, hasChronometer = true, isCountDown = false, whenOffset = (-5).minutes, expected = ExpectedTime.CountUp, ) } @Test @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME) fun extractTime_countUpFuture() { assertExtractedTime( hasTime = false, hasChronometer = true, isCountDown = false, whenOffset = 5.minutes, expected = ExpectedTime.CountUp, ) } @Test @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME) fun extractTime_countDownNow() { assertExtractedTime( hasTime = false, hasChronometer = true, isCountDown = true, whenOffset = Duration.ZERO, expected = ExpectedTime.CountDown, ) } @Test @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME) fun extractTime_countDownPast() { assertExtractedTime( hasTime = false, hasChronometer = true, isCountDown = true, whenOffset = (-5).minutes, expected = ExpectedTime.CountDown, ) } @Test @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME) fun extractTime_countDownFuture() { assertExtractedTime( hasTime = false, hasChronometer = true, isCountDown = true, whenOffset = 5.minutes, expected = ExpectedTime.CountDown, ) } @Test @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME) fun extractTime_prefersChronometerToWhen() { assertExtractedTime(hasTime = true, hasChronometer = true, expected = ExpectedTime.CountUp) } private enum class ExpectedTime { Null, Time, CountUp, CountDown, } private fun assertExtractedTime( hasTime: Boolean = false, hasChronometer: Boolean = false, isCountDown: Boolean = false, whenOffset: Duration = Duration.ZERO, expected: ExpectedTime, ) { // Set the two timebases to different (arbitrary) numbers, so we can verify whether the // extractor is doing the timebase adjustment correctly. systemClock.setCurrentTimeMillis(1_739_570_992_579L) systemClock.setElapsedRealtime(1_380_967_080L) val whenCurrentTime = systemClock.currentTimeMillis() + whenOffset.inWholeMilliseconds val whenElapsedRealtime = systemClock.elapsedRealtime() + whenOffset.inWholeMilliseconds val entry = createEntry { setShowWhen(hasTime) setUsesChronometer(hasChronometer) setChronometerCountDown(isCountDown) setWhen(whenCurrentTime) } val content = extractContent(entry) assertThat(content).isNotNull() when (expected) { ExpectedTime.Null -> assertThat(content?.time).isNull() ExpectedTime.Time -> { val actual = content?.time as? When.Time assertThat(actual).isNotNull() assertThat(actual?.currentTimeMillis).isEqualTo(whenCurrentTime) } ExpectedTime.CountDown, ExpectedTime.CountUp -> { val actual = content?.time as? When.Chronometer assertThat(actual).isNotNull() assertThat(actual?.elapsedRealtimeMillis).isEqualTo(whenElapsedRealtime) assertThat(actual?.isCountDown).isEqualTo(expected == ExpectedTime.CountDown) } } } @Test @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME) fun extractContent_fromBaseStyle() { val entry = createEntry { setStyle(null) } val content = extractContent(entry) Loading @@ -188,7 +363,7 @@ class PromotedNotificationContentExtractorImplTest : SysuiTestCase() { @Test @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME) fun extractsContent_fromBigPictureStyle() { fun extractContent_fromBigPictureStyle() { val entry = createEntry { setStyle(BigPictureStyle()) } val content = extractContent(entry) Loading Loading @@ -261,7 +436,7 @@ class PromotedNotificationContentExtractorImplTest : SysuiTestCase() { @Test @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME) fun extractsContent_fromOldProgressDeterminate() { fun extractContent_fromOldProgressDeterminate() { val entry = createEntry { setProgress(TEST_PROGRESS_MAX, TEST_PROGRESS, /* indeterminate= */ false) } Loading @@ -282,7 +457,7 @@ class PromotedNotificationContentExtractorImplTest : SysuiTestCase() { @Test @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME) fun extractsContent_fromOldProgressIndeterminate() { fun extractContent_fromOldProgressIndeterminate() { val entry = createEntry { setProgress(TEST_PROGRESS_MAX, TEST_PROGRESS, /* indeterminate= */ true) } Loading packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModel.kt +7 −17 Original line number Diff line number Diff line Loading @@ -161,17 +161,17 @@ constructor( ) } when (this.promotedContent.time.mode) { PromotedNotificationContentModel.When.Mode.BasicTime -> { when (this.promotedContent.time) { is PromotedNotificationContentModel.When.Time -> { return if ( this.promotedContent.time.time >= this.promotedContent.time.currentTimeMillis >= systemClock.currentTimeMillis() + FUTURE_TIME_THRESHOLD_MILLIS ) { OngoingActivityChipModel.Active.ShortTimeDelta( this.key, icon, colors, time = this.promotedContent.time.time, time = this.promotedContent.time.currentTimeMillis, onClickListenerLegacy, clickBehavior, ) Loading @@ -193,23 +193,13 @@ constructor( ) } } PromotedNotificationContentModel.When.Mode.CountUp -> { is PromotedNotificationContentModel.When.Chronometer -> { // TODO(b/364653005): Check isCountDown and support CountDown. return OngoingActivityChipModel.Active.Timer( this.key, icon, colors, startTimeMs = this.promotedContent.time.time, onClickListenerLegacy, clickBehavior, ) } PromotedNotificationContentModel.When.Mode.CountDown -> { // TODO(b/364653005): Support CountDown. return OngoingActivityChipModel.Active.Timer( this.key, icon, colors, startTimeMs = this.promotedContent.time.time, startTimeMs = this.promotedContent.time.elapsedRealtimeMillis, onClickListenerLegacy, clickBehavior, ) Loading packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt +4 −1 Original line number Diff line number Diff line Loading @@ -128,7 +128,10 @@ sealed class OngoingActivityChipModel { override val key: String, override val icon: ChipIcon, override val colors: ColorsModel, /** The time of the event that this chip represents. */ /** * The time of the event that this chip represents, relative to * [com.android.systemui.util.time.SystemClock.currentTimeMillis]. */ val time: Long, override val onClickListenerLegacy: View.OnClickListener?, override val clickBehavior: ClickBehavior, Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/AODPromotedNotification.kt +12 −15 Original line number Diff line number Diff line Loading @@ -386,24 +386,21 @@ private class AODPromotedNotificationViewUpdater(root: View) { setTextViewColor(time, SecondaryText) setTextViewColor(chronometer, SecondaryText) val timeValue = content.time if (timeValue == null) { time?.visibility = GONE chronometer?.visibility = GONE } else if (timeValue.mode == When.Mode.BasicTime) { time?.visibility = VISIBLE time?.setTime(timeValue.time) chronometer?.visibility = GONE } else { inflateChronometer() if (content.time is When.Time) { time?.setTime(content.time.currentTimeMillis) } time?.visibility = GONE chronometer?.visibility = VISIBLE chronometer?.base = timeValue.time chronometer?.isCountDown = (timeValue.mode == When.Mode.CountDown) if (content.time is When.Chronometer) { inflateChronometer() chronometer?.base = content.time.elapsedRealtimeMillis chronometer?.isCountDown = content.time.isCountDown chronometer?.setStarted(true) } else { chronometer?.stop() } time?.isVisible = (content.time is When.Time) chronometer?.isVisible = (content.time is When.Chronometer) } private fun updateSmallIcon( Loading Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelTest.kt +32 −73 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import com.android.systemui.statusbar.notification.data.repository.UnconfinedFak import com.android.systemui.statusbar.notification.data.repository.activeNotificationListRepository import com.android.systemui.statusbar.notification.headsup.PinnedStatus import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel.When import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel import com.android.systemui.statusbar.notification.stack.data.repository.headsUpNotificationRepository import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernization Loading Loading @@ -295,11 +296,7 @@ class NotifChipsViewModelTest : SysuiTestCase() { val promotedContentBuilder = PromotedNotificationContentModel.Builder("notif").apply { this.shortCriticalText = "Arrived" this.time = PromotedNotificationContentModel.When( time = currentTime + 30.minutes.inWholeMilliseconds, mode = PromotedNotificationContentModel.When.Mode.BasicTime, ) this.time = When.Time(currentTime + 30.minutes.inWholeMilliseconds) } setNotifs( listOf( Loading Loading @@ -351,11 +348,7 @@ class NotifChipsViewModelTest : SysuiTestCase() { val promotedContentBuilder = PromotedNotificationContentModel.Builder("notif").apply { this.wasPromotedAutomatically = true this.time = PromotedNotificationContentModel.When( time = currentTime + 30.minutes.inWholeMilliseconds, mode = PromotedNotificationContentModel.When.Mode.BasicTime, ) this.time = When.Time(currentTime + 30.minutes.inWholeMilliseconds) } setNotifs( listOf( Loading Loading @@ -383,11 +376,7 @@ class NotifChipsViewModelTest : SysuiTestCase() { val promotedContentBuilder = PromotedNotificationContentModel.Builder("notif").apply { this.wasPromotedAutomatically = false this.time = PromotedNotificationContentModel.When( time = currentTime + 30.minutes.inWholeMilliseconds, mode = PromotedNotificationContentModel.When.Mode.BasicTime, ) this.time = When.Time(currentTime + 30.minutes.inWholeMilliseconds) } setNotifs( listOf( Loading @@ -414,11 +403,7 @@ class NotifChipsViewModelTest : SysuiTestCase() { val promotedContentBuilder = PromotedNotificationContentModel.Builder("notif").apply { this.time = PromotedNotificationContentModel.When( time = currentTime + 13.minutes.inWholeMilliseconds, mode = PromotedNotificationContentModel.When.Mode.BasicTime, ) this.time = When.Time(currentTime + 13.minutes.inWholeMilliseconds) } setNotifs( Loading Loading @@ -446,11 +431,7 @@ class NotifChipsViewModelTest : SysuiTestCase() { val promotedContentBuilder = PromotedNotificationContentModel.Builder("notif").apply { this.time = PromotedNotificationContentModel.When( time = currentTime + 500, mode = PromotedNotificationContentModel.When.Mode.BasicTime, ) this.time = When.Time(currentTime + 500) } setNotifs( Loading Loading @@ -478,11 +459,7 @@ class NotifChipsViewModelTest : SysuiTestCase() { val promotedContentBuilder = PromotedNotificationContentModel.Builder("notif").apply { this.time = PromotedNotificationContentModel.When( time = currentTime, mode = PromotedNotificationContentModel.When.Mode.BasicTime, ) this.time = When.Time(currentTime) } setNotifs( Loading Loading @@ -510,11 +487,7 @@ class NotifChipsViewModelTest : SysuiTestCase() { val promotedContentBuilder = PromotedNotificationContentModel.Builder("notif").apply { this.time = PromotedNotificationContentModel.When( time = currentTime - 2.minutes.inWholeMilliseconds, mode = PromotedNotificationContentModel.When.Mode.BasicTime, ) this.time = When.Time(currentTime - 2.minutes.inWholeMilliseconds) } setNotifs( Loading Loading @@ -543,11 +516,7 @@ class NotifChipsViewModelTest : SysuiTestCase() { val promotedContentBuilder = PromotedNotificationContentModel.Builder("notif").apply { this.time = PromotedNotificationContentModel.When( time = currentTime + 3.minutes.inWholeMilliseconds, mode = PromotedNotificationContentModel.When.Mode.BasicTime, ) this.time = When.Time(currentTime + 3.minutes.inWholeMilliseconds) } setNotifs( Loading Loading @@ -579,13 +548,16 @@ class NotifChipsViewModelTest : SysuiTestCase() { val currentTime = 30.minutes.inWholeMilliseconds fakeSystemClock.setCurrentTimeMillis(currentTime) val currentElapsed = currentTime + fakeSystemClock.elapsedRealtime() - fakeSystemClock.currentTimeMillis() val whenElapsed = currentElapsed - 1.minutes.inWholeMilliseconds val promotedContentBuilder = PromotedNotificationContentModel.Builder("notif").apply { this.time = PromotedNotificationContentModel.When( time = currentTime + 10.minutes.inWholeMilliseconds, mode = PromotedNotificationContentModel.When.Mode.CountUp, ) When.Chronometer(elapsedRealtimeMillis = whenElapsed, isCountDown = false) } setNotifs( listOf( Loading @@ -599,6 +571,8 @@ class NotifChipsViewModelTest : SysuiTestCase() { assertThat(latest).hasSize(1) assertThat(latest!![0]).isInstanceOf(OngoingActivityChipModel.Active.Timer::class.java) assertThat((latest!![0] as OngoingActivityChipModel.Active.Timer).startTimeMs) .isEqualTo(whenElapsed) } @Test Loading @@ -609,13 +583,16 @@ class NotifChipsViewModelTest : SysuiTestCase() { val currentTime = 30.minutes.inWholeMilliseconds fakeSystemClock.setCurrentTimeMillis(currentTime) val currentElapsed = currentTime + fakeSystemClock.elapsedRealtime() - fakeSystemClock.currentTimeMillis() val whenElapsed = currentElapsed + 10.minutes.inWholeMilliseconds val promotedContentBuilder = PromotedNotificationContentModel.Builder("notif").apply { this.time = PromotedNotificationContentModel.When( time = currentTime + 10.minutes.inWholeMilliseconds, mode = PromotedNotificationContentModel.When.Mode.CountDown, ) When.Chronometer(elapsedRealtimeMillis = whenElapsed, isCountDown = true) } setNotifs( listOf( Loading @@ -629,6 +606,8 @@ class NotifChipsViewModelTest : SysuiTestCase() { assertThat(latest).hasSize(1) assertThat(latest!![0]).isInstanceOf(OngoingActivityChipModel.Active.Timer::class.java) assertThat((latest!![0] as OngoingActivityChipModel.Active.Timer).startTimeMs) .isEqualTo(whenElapsed) } @Test Loading @@ -641,11 +620,7 @@ class NotifChipsViewModelTest : SysuiTestCase() { val promotedContentBuilder = PromotedNotificationContentModel.Builder("notif").apply { this.time = PromotedNotificationContentModel.When( time = currentTime + 10.minutes.inWholeMilliseconds, mode = PromotedNotificationContentModel.When.Mode.BasicTime, ) this.time = When.Time(currentTime + 10.minutes.inWholeMilliseconds) } setNotifs( listOf( Loading Loading @@ -675,11 +650,7 @@ class NotifChipsViewModelTest : SysuiTestCase() { val promotedContentBuilder = PromotedNotificationContentModel.Builder("notif").apply { this.time = PromotedNotificationContentModel.When( time = currentTime + 10.minutes.inWholeMilliseconds, mode = PromotedNotificationContentModel.When.Mode.BasicTime, ) this.time = When.Time(currentTime + 10.minutes.inWholeMilliseconds) } setNotifs( listOf( Loading Loading @@ -716,19 +687,11 @@ class NotifChipsViewModelTest : SysuiTestCase() { val promotedContentBuilder = PromotedNotificationContentModel.Builder("notif").apply { this.time = PromotedNotificationContentModel.When( time = currentTime + 10.minutes.inWholeMilliseconds, mode = PromotedNotificationContentModel.When.Mode.BasicTime, ) this.time = When.Time(currentTime + 10.minutes.inWholeMilliseconds) } val otherPromotedContentBuilder = PromotedNotificationContentModel.Builder("other notif").apply { this.time = PromotedNotificationContentModel.When( time = currentTime + 10.minutes.inWholeMilliseconds, mode = PromotedNotificationContentModel.When.Mode.BasicTime, ) this.time = When.Time(currentTime + 10.minutes.inWholeMilliseconds) } val icon = createStatusBarIconViewOrNull() val otherIcon = createStatusBarIconViewOrNull() Loading Loading @@ -772,11 +735,7 @@ class NotifChipsViewModelTest : SysuiTestCase() { val promotedContentBuilder = PromotedNotificationContentModel.Builder("notif").apply { this.time = PromotedNotificationContentModel.When( time = currentTime + 10.minutes.inWholeMilliseconds, mode = PromotedNotificationContentModel.When.Mode.BasicTime, ) this.time = When.Time(currentTime + 10.minutes.inWholeMilliseconds) } setNotifs( listOf( Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorImplTest.kt +180 −5 Original line number Diff line number Diff line Loading @@ -39,18 +39,24 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntryB import com.android.systemui.statusbar.notification.promoted.AutomaticPromotionCoordinator.Companion.EXTRA_WAS_AUTOMATICALLY_PROMOTED import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel.Style import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel.When import com.android.systemui.statusbar.notification.row.RowImageInflater import com.android.systemui.testKosmos import com.android.systemui.util.time.fakeSystemClock import com.android.systemui.util.time.systemClock import com.google.common.truth.Truth.assertThat import kotlin.time.Duration import kotlin.time.Duration.Companion.minutes import org.junit.Test import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class PromotedNotificationContentExtractorImplTest : SysuiTestCase() { private val kosmos = testKosmos() private val kosmos = testKosmos().apply { systemClock = fakeSystemClock } private val underTest = kosmos.promotedNotificationContentExtractor private val systemClock = kosmos.fakeSystemClock private val rowImageInflater = RowImageInflater.newInstance(previousIndex = null) private val imageModelProvider by lazy { rowImageInflater.useForContentModel() } Loading Loading @@ -177,7 +183,176 @@ class PromotedNotificationContentExtractorImplTest : SysuiTestCase() { @Test @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME) fun extractsContent_fromBaseStyle() { fun extractTime_none() { assertExtractedTime(hasTime = false, hasChronometer = false, expected = ExpectedTime.Null) } @Test @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME) fun extractTime_basicTimeNow() { assertExtractedTime( hasTime = true, hasChronometer = false, whenOffset = Duration.ZERO, expected = ExpectedTime.Time, ) } @Test @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME) fun extractTime_basicTimePast() { assertExtractedTime( hasTime = true, hasChronometer = false, whenOffset = (-5).minutes, expected = ExpectedTime.Time, ) } @Test @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME) fun extractTime_basicTimeFuture() { assertExtractedTime( hasTime = true, hasChronometer = false, whenOffset = 5.minutes, expected = ExpectedTime.Time, ) } @Test @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME) fun extractTime_countUpNow() { assertExtractedTime( hasTime = false, hasChronometer = true, isCountDown = false, whenOffset = Duration.ZERO, expected = ExpectedTime.CountUp, ) } @Test @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME) fun extractTime_countUpPast() { assertExtractedTime( hasTime = false, hasChronometer = true, isCountDown = false, whenOffset = (-5).minutes, expected = ExpectedTime.CountUp, ) } @Test @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME) fun extractTime_countUpFuture() { assertExtractedTime( hasTime = false, hasChronometer = true, isCountDown = false, whenOffset = 5.minutes, expected = ExpectedTime.CountUp, ) } @Test @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME) fun extractTime_countDownNow() { assertExtractedTime( hasTime = false, hasChronometer = true, isCountDown = true, whenOffset = Duration.ZERO, expected = ExpectedTime.CountDown, ) } @Test @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME) fun extractTime_countDownPast() { assertExtractedTime( hasTime = false, hasChronometer = true, isCountDown = true, whenOffset = (-5).minutes, expected = ExpectedTime.CountDown, ) } @Test @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME) fun extractTime_countDownFuture() { assertExtractedTime( hasTime = false, hasChronometer = true, isCountDown = true, whenOffset = 5.minutes, expected = ExpectedTime.CountDown, ) } @Test @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME) fun extractTime_prefersChronometerToWhen() { assertExtractedTime(hasTime = true, hasChronometer = true, expected = ExpectedTime.CountUp) } private enum class ExpectedTime { Null, Time, CountUp, CountDown, } private fun assertExtractedTime( hasTime: Boolean = false, hasChronometer: Boolean = false, isCountDown: Boolean = false, whenOffset: Duration = Duration.ZERO, expected: ExpectedTime, ) { // Set the two timebases to different (arbitrary) numbers, so we can verify whether the // extractor is doing the timebase adjustment correctly. systemClock.setCurrentTimeMillis(1_739_570_992_579L) systemClock.setElapsedRealtime(1_380_967_080L) val whenCurrentTime = systemClock.currentTimeMillis() + whenOffset.inWholeMilliseconds val whenElapsedRealtime = systemClock.elapsedRealtime() + whenOffset.inWholeMilliseconds val entry = createEntry { setShowWhen(hasTime) setUsesChronometer(hasChronometer) setChronometerCountDown(isCountDown) setWhen(whenCurrentTime) } val content = extractContent(entry) assertThat(content).isNotNull() when (expected) { ExpectedTime.Null -> assertThat(content?.time).isNull() ExpectedTime.Time -> { val actual = content?.time as? When.Time assertThat(actual).isNotNull() assertThat(actual?.currentTimeMillis).isEqualTo(whenCurrentTime) } ExpectedTime.CountDown, ExpectedTime.CountUp -> { val actual = content?.time as? When.Chronometer assertThat(actual).isNotNull() assertThat(actual?.elapsedRealtimeMillis).isEqualTo(whenElapsedRealtime) assertThat(actual?.isCountDown).isEqualTo(expected == ExpectedTime.CountDown) } } } @Test @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME) fun extractContent_fromBaseStyle() { val entry = createEntry { setStyle(null) } val content = extractContent(entry) Loading @@ -188,7 +363,7 @@ class PromotedNotificationContentExtractorImplTest : SysuiTestCase() { @Test @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME) fun extractsContent_fromBigPictureStyle() { fun extractContent_fromBigPictureStyle() { val entry = createEntry { setStyle(BigPictureStyle()) } val content = extractContent(entry) Loading Loading @@ -261,7 +436,7 @@ class PromotedNotificationContentExtractorImplTest : SysuiTestCase() { @Test @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME) fun extractsContent_fromOldProgressDeterminate() { fun extractContent_fromOldProgressDeterminate() { val entry = createEntry { setProgress(TEST_PROGRESS_MAX, TEST_PROGRESS, /* indeterminate= */ false) } Loading @@ -282,7 +457,7 @@ class PromotedNotificationContentExtractorImplTest : SysuiTestCase() { @Test @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME) fun extractsContent_fromOldProgressIndeterminate() { fun extractContent_fromOldProgressIndeterminate() { val entry = createEntry { setProgress(TEST_PROGRESS_MAX, TEST_PROGRESS, /* indeterminate= */ true) } Loading
packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModel.kt +7 −17 Original line number Diff line number Diff line Loading @@ -161,17 +161,17 @@ constructor( ) } when (this.promotedContent.time.mode) { PromotedNotificationContentModel.When.Mode.BasicTime -> { when (this.promotedContent.time) { is PromotedNotificationContentModel.When.Time -> { return if ( this.promotedContent.time.time >= this.promotedContent.time.currentTimeMillis >= systemClock.currentTimeMillis() + FUTURE_TIME_THRESHOLD_MILLIS ) { OngoingActivityChipModel.Active.ShortTimeDelta( this.key, icon, colors, time = this.promotedContent.time.time, time = this.promotedContent.time.currentTimeMillis, onClickListenerLegacy, clickBehavior, ) Loading @@ -193,23 +193,13 @@ constructor( ) } } PromotedNotificationContentModel.When.Mode.CountUp -> { is PromotedNotificationContentModel.When.Chronometer -> { // TODO(b/364653005): Check isCountDown and support CountDown. return OngoingActivityChipModel.Active.Timer( this.key, icon, colors, startTimeMs = this.promotedContent.time.time, onClickListenerLegacy, clickBehavior, ) } PromotedNotificationContentModel.When.Mode.CountDown -> { // TODO(b/364653005): Support CountDown. return OngoingActivityChipModel.Active.Timer( this.key, icon, colors, startTimeMs = this.promotedContent.time.time, startTimeMs = this.promotedContent.time.elapsedRealtimeMillis, onClickListenerLegacy, clickBehavior, ) Loading
packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt +4 −1 Original line number Diff line number Diff line Loading @@ -128,7 +128,10 @@ sealed class OngoingActivityChipModel { override val key: String, override val icon: ChipIcon, override val colors: ColorsModel, /** The time of the event that this chip represents. */ /** * The time of the event that this chip represents, relative to * [com.android.systemui.util.time.SystemClock.currentTimeMillis]. */ val time: Long, override val onClickListenerLegacy: View.OnClickListener?, override val clickBehavior: ClickBehavior, Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/AODPromotedNotification.kt +12 −15 Original line number Diff line number Diff line Loading @@ -386,24 +386,21 @@ private class AODPromotedNotificationViewUpdater(root: View) { setTextViewColor(time, SecondaryText) setTextViewColor(chronometer, SecondaryText) val timeValue = content.time if (timeValue == null) { time?.visibility = GONE chronometer?.visibility = GONE } else if (timeValue.mode == When.Mode.BasicTime) { time?.visibility = VISIBLE time?.setTime(timeValue.time) chronometer?.visibility = GONE } else { inflateChronometer() if (content.time is When.Time) { time?.setTime(content.time.currentTimeMillis) } time?.visibility = GONE chronometer?.visibility = VISIBLE chronometer?.base = timeValue.time chronometer?.isCountDown = (timeValue.mode == When.Mode.CountDown) if (content.time is When.Chronometer) { inflateChronometer() chronometer?.base = content.time.elapsedRealtimeMillis chronometer?.isCountDown = content.time.isCountDown chronometer?.setStarted(true) } else { chronometer?.stop() } time?.isVisible = (content.time is When.Time) chronometer?.isVisible = (content.time is When.Chronometer) } private fun updateSmallIcon( Loading