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

Commit 421af409 authored by Xiaowen Lei's avatar Xiaowen Lei Committed by Android (Google) Code Review
Browse files

Merge "Some UI updates to timer RON per the initial UX mock." into main

parents b6a35f11 ede75a98
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@

package com.android.systemui.statusbar.notification.row.ui.viewmodel

import android.app.Notification
import android.app.PendingIntent
import android.platform.test.annotations.EnableFlags
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -90,7 +91,8 @@ class TimerViewModelTest : SysuiTestCase() {
        name: String = "example",
        timeRemaining: Duration = Duration.ofMinutes(3),
        resumeIntent: PendingIntent? = null,
        resetIntent: PendingIntent? = null
        addMinuteAction: Notification.Action? = null,
        resetAction: Notification.Action? = null
    ) =
        TimerContentModel(
            icon = icon,
@@ -99,7 +101,8 @@ class TimerViewModelTest : SysuiTestCase() {
                Paused(
                    timeRemaining = timeRemaining,
                    resumeIntent = resumeIntent,
                    resetIntent = resetIntent,
                    addMinuteAction = addMinuteAction,
                    resetAction = resetAction,
                )
        )
}
+13 −7
Original line number Diff line number Diff line
@@ -33,7 +33,6 @@
        android:id="@+id/icon"
        android:layout_width="24dp"
        android:layout_height="24dp"
        android:src="@drawable/ic_close"
        app:tint="@android:color/white"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toStartOf="@id/label"
@@ -88,11 +87,10 @@
        />

    <com.android.systemui.statusbar.notification.row.ui.view.TimerButtonView
        style="@*android:style/NotificationEmphasizedAction"
        android:id="@+id/mainButton"
        android:layout_width="124dp"
        android:layout_height="wrap_content"
        tools:text="Reset"
        tools:drawableStart="@android:drawable/ic_menu_add"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toStartOf="@id/altButton"
        app:layout_constraintTop_toBottomOf="@id/bottomOfTop"
@@ -101,15 +99,23 @@
        />

    <com.android.systemui.statusbar.notification.row.ui.view.TimerButtonView
        style="@*android:style/NotificationEmphasizedAction"
        android:id="@+id/altButton"
        tools:text="Reset"
        tools:drawableStart="@android:drawable/ic_menu_add"
        android:drawablePadding="2dp"
        android:drawableTint="@android:color/white"
        android:layout_width="124dp"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@id/bottomOfTop"
        app:layout_constraintStart_toEndOf="@id/mainButton"
        app:layout_constraintEnd_toEndOf="@id/resetButton"
        android:paddingEnd="4dp"
        />

    <com.android.systemui.statusbar.notification.row.ui.view.TimerButtonView
        style="@*android:style/NotificationEmphasizedAction"
        android:id="@+id/resetButton"
        android:layout_width="124dp"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@id/bottomOfTop"
        app:layout_constraintStart_toEndOf="@id/altButton"
        app:layout_constraintEnd_toEndOf="parent"
        android:paddingEnd="4dp"
        />
+40 −8
Original line number Diff line number Diff line
@@ -122,12 +122,15 @@ class RichOngoingNotificationContentExtractorImpl @Inject constructor() :
                val timeRemaining = parseTimeDelta(remaining)
                TimerContentModel(
                    icon = icon,
                    name = total,
                    // TODO: b/352142761 - define and use a string resource rather than " Timer".
                    // (The UX isn't final so using " Timer" for now).
                    name = total.replace("Σ", "") + " Timer",
                    state =
                        TimerContentModel.TimerState.Paused(
                            timeRemaining = timeRemaining,
                            resumeIntent = notification.findActionWithName("Resume"),
                            resetIntent = notification.findActionWithName("Reset"),
                            resumeIntent = notification.findStartIntent(),
                            addMinuteAction = notification.findAddMinuteAction(),
                            resetAction = notification.findResetAction(),
                        )
                )
            }
@@ -136,12 +139,15 @@ class RichOngoingNotificationContentExtractorImpl @Inject constructor() :
                val finishTime = parseCurrentTime(current) + parseTimeDelta(remaining).toMillis()
                TimerContentModel(
                    icon = icon,
                    name = total,
                    // TODO: b/352142761 - define and use a string resource rather than " Timer".
                    // (The UX isn't final so using " Timer" for now).
                    name = total.replace("Σ", "") + " Timer",
                    state =
                        TimerContentModel.TimerState.Running(
                            finishTime = finishTime,
                            pauseIntent = notification.findActionWithName("Pause"),
                            addOneMinuteIntent = notification.findActionWithName("Add 1 min"),
                            pauseIntent = notification.findPauseIntent(),
                            addMinuteAction = notification.findAddMinuteAction(),
                            resetAction = notification.findResetAction(),
                        )
                )
            }
@@ -149,8 +155,34 @@ class RichOngoingNotificationContentExtractorImpl @Inject constructor() :
        }
    }

    private fun Notification.findActionWithName(name: String): PendingIntent? {
        return actions.firstOrNull { name == it.title?.toString() }?.actionIntent
    private fun Notification.findPauseIntent(): PendingIntent? {
        return actions
            .firstOrNull { it.actionIntent.intent?.action?.endsWith(".PAUSE_TIMER") == true }
            ?.actionIntent
    }

    private fun Notification.findStartIntent(): PendingIntent? {
        return actions
            .firstOrNull { it.actionIntent.intent?.action?.endsWith(".START_TIMER") == true }
            ?.actionIntent
    }

    // TODO: b/352142761 - switch to system attributes for label and icon.
    //   - We probably want a consistent look for the Reset button. (Double check with UX.)
    //   - Using the custom assets now since I couldn't an existing "Reset" icon.
    private fun Notification.findResetAction(): Notification.Action? {
        return actions.firstOrNull {
            it.actionIntent.intent?.action?.endsWith(".RESET_TIMER") == true
        }
    }

    // TODO: b/352142761 - check with UX on whether this should be required.
    //   - Alternative is to allow for optional actions in addition to main and reset.
    //   - For optional actions, we should take the custom label and icon.
    private fun Notification.findAddMinuteAction(): Notification.Action? {
        return actions.firstOrNull {
            it.actionIntent.intent?.action?.endsWith(".ADD_MINUTE_TIMER") == true
        }
    }

    private fun parseCurrentTime(current: String): Long {
+8 −2
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.systemui.statusbar.notification.row.shared

import android.app.Notification
import android.app.PendingIntent
import java.time.Duration

@@ -32,6 +33,9 @@ data class TimerContentModel(
) : RichOngoingContentModel {
    /** The state (paused or running) of the timer, and relevant time */
    sealed interface TimerState {
        val addMinuteAction: Notification.Action?
        val resetAction: Notification.Action?

        /**
         * Indicates a running timer
         *
@@ -41,7 +45,8 @@ data class TimerContentModel(
        data class Running(
            val finishTime: Long,
            val pauseIntent: PendingIntent?,
            val addOneMinuteIntent: PendingIntent?,
            override val addMinuteAction: Notification.Action?,
            override val resetAction: Notification.Action?,
        ) : TimerState

        /**
@@ -53,7 +58,8 @@ data class TimerContentModel(
        data class Paused(
            val timeRemaining: Duration,
            val resumeIntent: PendingIntent?,
            val resetIntent: PendingIntent?,
            override val addMinuteAction: Notification.Action?,
            override val resetAction: Notification.Action?,
        ) : TimerState
    }
}
+8 −2
Original line number Diff line number Diff line
@@ -18,8 +18,9 @@ package com.android.systemui.statusbar.notification.row.ui.view

import android.annotation.DrawableRes
import android.content.Context
import android.graphics.BlendMode
import android.util.AttributeSet
import android.widget.Button
import com.android.internal.widget.EmphasizedNotificationButton

class TimerButtonView
@JvmOverloads
@@ -28,14 +29,19 @@ constructor(
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0,
    defStyleRes: Int = 0,
) : Button(context, attrs, defStyleAttr, defStyleRes) {
) : EmphasizedNotificationButton(context, attrs, defStyleAttr, defStyleRes) {

    private val Int.dp: Int
        get() = (this * context.resources.displayMetrics.density).toInt()

    fun setIcon(@DrawableRes icon: Int) {
        val drawable = context.getDrawable(icon)

        drawable?.mutate()
        drawable?.setTintList(textColors)
        drawable?.setTintBlendMode(BlendMode.SRC_IN)
        drawable?.setBounds(0, 0, 24.dp, 24.dp)

        setCompoundDrawablesRelative(drawable, null, null, null)
    }
}
Loading