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

Commit 6cae9ea1 authored by yyhua's avatar yyhua
Browse files

[AnimatedAction] Set the new button style for animated reply behind the flag.

Next
- Add corresponding tests in the follow-up cl

Bug: 383567383
Test: atest SmartActionScreenshotTest
Flag: com.android.systemui.notification_animated_actions_treatment
Change-Id: I7fc917510b6494caf9049140ca6fd64d8ebe0adb
parent 97faf816
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -148,6 +148,7 @@
    <!-- Animated Action colors -->
    <color name="animated_action_button_text_color">@androidprv:color/materialColorOnSurface</color>
    <color name="animated_action_button_stroke_color">@androidprv:color/materialColorOnSurface</color>
    <color name="animated_action_button_attribution_color">@androidprv:color/materialColorOnSurfaceVariant</color>

    <!-- Biometric dialog colors -->
    <color name="biometric_dialog_gray">#ff757575</color>
+73 −3
Original line number Diff line number Diff line
@@ -34,6 +34,10 @@ import android.graphics.drawable.Icon
import android.os.Build
import android.os.Bundle
import android.os.SystemClock
import android.text.Annotation
import android.text.SpannableStringBuilder
import android.text.Spanned
import android.text.style.ForegroundColorSpan
import android.util.Log
import android.view.ContextThemeWrapper
import android.view.LayoutInflater
@@ -504,15 +508,40 @@ constructor(
        choice: CharSequence,
        delayOnClickListener: Boolean,
    ): Button {
        val layoutRes =
        val enableAnimatedReply = Flags.notificationAnimatedActionsTreatment() &&
                smartReplies.fromAssistant && isAnimatedReply(choice)
        val layoutRes = if (enableAnimatedReply) {
            R.layout.animated_action_button
        } else {
            if (notificationsRedesignTemplates()) R.layout.notification_2025_smart_reply_button
            else R.layout.smart_reply_button
        }

        return (LayoutInflater.from(parent.context).inflate(layoutRes, parent, false) as Button)
            .apply {
                // choiceToDeliver does not contain Annotation with extra data
                val choiceToDeliver: CharSequence
                if (enableAnimatedReply) {
                    choiceToDeliver = choice.toString()
                    // If the choice is animated reply, format the text by concatenating
                    // attributionText with different color to choice text
                    val fullTextWithAttribution = formatChoiceWithAttribution(choice)
                    text = fullTextWithAttribution
                } else {
                    choiceToDeliver = choice
                    text = choice
                }

                val onClickListener =
                    View.OnClickListener {
                        onSmartReplyClick(entry, smartReplies, replyIndex, parent, this, choice)
                        onSmartReplyClick(
                            entry,
                            smartReplies,
                            replyIndex,
                            parent,
                            this,
                            choiceToDeliver
                        )
                    }
                setOnClickListener(
                    if (delayOnClickListener)
@@ -600,6 +629,47 @@ constructor(
        RemoteInput.setResultsSource(intent, RemoteInput.SOURCE_CHOICE)
        return intent
    }

    // Check if the choice is animated reply
    private fun isAnimatedReply(choice: CharSequence): Boolean {
        if (choice is Spanned) {
            val annotations = choice.getSpans(0, choice.length, Annotation::class.java)
            for (annotation in annotations) {
                if (annotation.key == "isAnimatedReply" && annotation.value == "1") {
                    return true
                }
            }
        }
        return false
    }

    // Format the text by concatenating attributionText with attribution text color to choice text
    private fun formatChoiceWithAttribution(choice: CharSequence): CharSequence {
        val colorInt = context.getColor(R.color.animated_action_button_attribution_color)
        if (choice is Spanned) {
            val annotations = choice.getSpans(0, choice.length, Annotation::class.java)
            for (annotation in annotations) {
                if (annotation.key == "attributionText") {
                    // Extract the attribution text
                    val extraText = annotation.value
                    // Concatenate choice text and attribution text
                    val spannableWithColor = SpannableStringBuilder(choice)
                    spannableWithColor.append(" $extraText")
                    // Apply color to attribution text
                    spannableWithColor.setSpan(
                        ForegroundColorSpan(colorInt),
                        choice.length,
                        spannableWithColor.length,
                        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                    )
                    return spannableWithColor
                }
            }
        }

        // Return the original if no attributionText found
        return choice.toString()
    }
}

/**