Merge "Hide time on Tile for alarms further than a week" into main
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/alarm/domain/AlarmTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/alarm/domain/AlarmTileMapperTest.kt
index 00405d0..c2ce392 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/alarm/domain/AlarmTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/alarm/domain/AlarmTileMapperTest.kt
@@ -29,27 +29,37 @@
import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject
import com.android.systemui.qs.tiles.viewmodel.QSTileState
import com.android.systemui.res.R
+import com.android.systemui.util.time.FakeSystemClock
import java.time.Instant
import java.time.LocalDateTime
import java.util.TimeZone
+import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@SmallTest
@RunWith(AndroidJUnit4::class)
class AlarmTileMapperTest : SysuiTestCase() {
+ private val oneMinute = 60000L
private val kosmos = Kosmos()
private val alarmTileConfig = kosmos.qsAlarmTileConfig
+ private val fakeClock = FakeSystemClock()
// Using lazy (versus =) to make sure we override the right context -- see b/311612168
private val mapper by lazy {
AlarmTileMapper(
context.orCreateTestableResources
.apply { addOverride(R.drawable.ic_alarm, TestStubDrawable()) }
.resources,
- context.theme
+ context.theme,
+ fakeClock
)
}
+ @Before
+ fun setup() {
+ fakeClock.setCurrentTimeMillis(0) // same time both in test & map()
+ }
+
@Test
fun notAlarmSet() {
val inputModel = AlarmTileModel.NoAlarmSet
@@ -66,7 +76,7 @@
@Test
fun nextAlarmSet24HourFormat() {
- val triggerTime = 1L
+ val triggerTime = fakeClock.currentTimeMillis() + oneMinute
val inputModel =
AlarmTileModel.NextAlarmSet(true, AlarmManager.AlarmClockInfo(triggerTime, null))
@@ -85,7 +95,7 @@
@Test
fun nextAlarmSet12HourFormat() {
- val triggerTime = 1L
+ val triggerTime = fakeClock.currentTimeMillis() + oneMinute
val inputModel =
AlarmTileModel.NextAlarmSet(false, AlarmManager.AlarmClockInfo(triggerTime, null))
@@ -102,6 +112,66 @@
QSTileStateSubject.assertThat(outputState).isEqualTo(expectedState)
}
+ @Test
+ fun nextAlarmSetMoreThanAWeekLater_mapsSecondaryLabelToDisplayDateOnly() {
+ val oneWeekAndOneMinute = 7 * 24 * 60 * 60 * 1000L + oneMinute
+ val triggerTime = fakeClock.currentTimeMillis() + oneWeekAndOneMinute
+ val inputModel =
+ AlarmTileModel.NextAlarmSet(false, AlarmManager.AlarmClockInfo(triggerTime, null))
+
+ val outputState = mapper.map(alarmTileConfig, inputModel)
+
+ val localDateTime =
+ LocalDateTime.ofInstant(
+ Instant.ofEpochMilli(triggerTime),
+ TimeZone.getDefault().toZoneId()
+ )
+ val expectedSecondaryLabel = AlarmTileMapper.formatterDateOnly.format(localDateTime)
+ val expectedState =
+ createAlarmTileState(QSTileState.ActivationState.ACTIVE, expectedSecondaryLabel)
+ QSTileStateSubject.assertThat(outputState).isEqualTo(expectedState)
+ }
+
+ @Test
+ fun nextAlarmSetOneMinuteLessThanAWeekLater_mapsSecondaryLabelToDisplayTime() {
+ val oneWeekMinusOneMinute = 7 * 24 * 60 * 60 * 1000L - oneMinute
+ val triggerTime = fakeClock.currentTimeMillis() + oneWeekMinusOneMinute
+ val inputModel =
+ AlarmTileModel.NextAlarmSet(false, AlarmManager.AlarmClockInfo(triggerTime, null))
+
+ val outputState = mapper.map(alarmTileConfig, inputModel)
+
+ val localDateTime =
+ LocalDateTime.ofInstant(
+ Instant.ofEpochMilli(triggerTime),
+ TimeZone.getDefault().toZoneId()
+ )
+ val expectedSecondaryLabel = AlarmTileMapper.formatter12Hour.format(localDateTime)
+ val expectedState =
+ createAlarmTileState(QSTileState.ActivationState.ACTIVE, expectedSecondaryLabel)
+ QSTileStateSubject.assertThat(outputState).isEqualTo(expectedState)
+ }
+
+ @Test
+ fun nextAlarmSetExactlyAWeekLater_mapsSecondaryLabelToDisplayDateOnly() {
+ val oneWeek = 7 * 24 * 60 * 60 * 1000L
+ val triggerTime = fakeClock.currentTimeMillis() + oneWeek
+ val inputModel =
+ AlarmTileModel.NextAlarmSet(false, AlarmManager.AlarmClockInfo(triggerTime, null))
+
+ val outputState = mapper.map(alarmTileConfig, inputModel)
+
+ val localDateTime =
+ LocalDateTime.ofInstant(
+ Instant.ofEpochMilli(triggerTime),
+ TimeZone.getDefault().toZoneId()
+ )
+ val expectedSecondaryLabel = AlarmTileMapper.formatterDateOnly.format(localDateTime)
+ val expectedState =
+ createAlarmTileState(QSTileState.ActivationState.ACTIVE, expectedSecondaryLabel)
+ QSTileStateSubject.assertThat(outputState).isEqualTo(expectedState)
+ }
+
private fun createAlarmTileState(
activationState: QSTileState.ActivationState,
secondaryLabel: String
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/alarm/domain/AlarmTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/alarm/domain/AlarmTileMapper.kt
index e075e76..2b8c335 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/alarm/domain/AlarmTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/alarm/domain/AlarmTileMapper.kt
@@ -24,6 +24,7 @@
import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
import com.android.systemui.qs.tiles.viewmodel.QSTileState
import com.android.systemui.res.R
+import com.android.systemui.util.time.SystemClock
import java.time.Instant
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
@@ -36,10 +37,12 @@
constructor(
@Main private val resources: Resources,
private val theme: Theme,
+ private val clock: SystemClock,
) : QSTileDataToStateMapper<AlarmTileModel> {
companion object {
val formatter12Hour: DateTimeFormatter = DateTimeFormatter.ofPattern("E hh:mm a")
val formatter24Hour: DateTimeFormatter = DateTimeFormatter.ofPattern("E HH:mm")
+ val formatterDateOnly: DateTimeFormatter = DateTimeFormatter.ofPattern("E MMM d")
}
override fun map(config: QSTileConfig, data: AlarmTileModel): QSTileState =
QSTileState.build(resources, theme, config.uiConfig) {
@@ -47,14 +50,32 @@
is AlarmTileModel.NextAlarmSet -> {
activationState = QSTileState.ActivationState.ACTIVE
- val localDateTime =
+ val alarmDateTime =
LocalDateTime.ofInstant(
Instant.ofEpochMilli(data.alarmClockInfo.triggerTime),
TimeZone.getDefault().toZoneId()
)
- secondaryLabel =
- if (data.is24HourFormat) formatter24Hour.format(localDateTime)
- else formatter12Hour.format(localDateTime)
+
+ val nowDateTime =
+ LocalDateTime.ofInstant(
+ Instant.ofEpochMilli(clock.currentTimeMillis()),
+ TimeZone.getDefault().toZoneId()
+ )
+
+ // Edge case: If it's 8:00:30 right now and alarm is requested for next week at
+ // 8:00:29, we still want to show the date. Same at nanosecond level.
+ val nextWeekThisTime = nowDateTime.plusWeeks(1).withSecond(0).withNano(0)
+
+ // is the alarm over a week away?
+ val shouldShowDateAndHideTime = alarmDateTime >= nextWeekThisTime
+
+ if (shouldShowDateAndHideTime) {
+ secondaryLabel = formatterDateOnly.format(alarmDateTime)
+ } else {
+ secondaryLabel =
+ if (data.is24HourFormat) formatter24Hour.format(alarmDateTime)
+ else formatter12Hour.format(alarmDateTime)
+ }
}
is AlarmTileModel.NoAlarmSet -> {
activationState = QSTileState.ActivationState.INACTIVE