Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dbaf83e0 authored by Behnam Heydarshahi's avatar Behnam Heydarshahi
Browse files

Hide time on Tile for alarms further than a week

Also shows month and day on the tile to signal next week(s).
This fixes a bug where pausing an alarm for a week would not get
reflected on a tile since the tile only dispaled day of week and time.

Fixes: 317279939
Flag: aconfig com.android.systemui.qs_new_tiles DEVELOPMENT
Test: atest SystemUiRoboTests:com.android.systemui.qs.tiles.impl.alarm.domain.AlarmTileMapperTest
Test: atest AlarmTileMapperTest
Change-Id: Ic9ccafdaff22a2b745bf91f1454aefc862688586
parent be1761a0
Loading
Loading
Loading
Loading
+73 −3
Original line number Diff line number Diff line
@@ -29,27 +29,37 @@ import com.android.systemui.qs.tiles.impl.alarm.qsAlarmTileConfig
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 @@ class AlarmTileMapperTest : SysuiTestCase() {

    @Test
    fun nextAlarmSet24HourFormat() {
        val triggerTime = 1L
        val triggerTime = fakeClock.currentTimeMillis() + oneMinute
        val inputModel =
            AlarmTileModel.NextAlarmSet(true, AlarmManager.AlarmClockInfo(triggerTime, null))

@@ -85,7 +95,7 @@ class AlarmTileMapperTest : SysuiTestCase() {

    @Test
    fun nextAlarmSet12HourFormat() {
        val triggerTime = 1L
        val triggerTime = fakeClock.currentTimeMillis() + oneMinute
        val inputModel =
            AlarmTileModel.NextAlarmSet(false, AlarmManager.AlarmClockInfo(triggerTime, null))

@@ -102,6 +112,66 @@ class AlarmTileMapperTest : SysuiTestCase() {
        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
+25 −4
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import com.android.systemui.qs.tiles.impl.alarm.domain.model.AlarmTileModel
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 @@ class AlarmTileMapper
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 @@ constructor(
                is AlarmTileModel.NextAlarmSet -> {
                    activationState = QSTileState.ActivationState.ACTIVE

                    val localDateTime =
                    val alarmDateTime =
                        LocalDateTime.ofInstant(
                            Instant.ofEpochMilli(data.alarmClockInfo.triggerTime),
                            TimeZone.getDefault().toZoneId()
                        )

                    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(localDateTime)
                        else formatter12Hour.format(localDateTime)
                            if (data.is24HourFormat) formatter24Hour.format(alarmDateTime)
                            else formatter12Hour.format(alarmDateTime)
                    }
                }
                is AlarmTileModel.NoAlarmSet -> {
                    activationState = QSTileState.ActivationState.INACTIVE