diff options
9 files changed, 83 insertions, 10 deletions
diff --git a/core/res/res/drawable/ic_notification_summarization.xml b/core/res/res/drawable/ic_notification_summarization.xml new file mode 100644 index 000000000000..de905fa10728 --- /dev/null +++ b/core/res/res/drawable/ic_notification_summarization.xml @@ -0,0 +1,23 @@ +<!-- +Copyright (C) 2025 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="16dp" + android:height="16dp" + android:tint="?android:attr/colorControlNormal" + android:viewportHeight="960" + android:viewportWidth="960"> + <path android:fillColor="#ffffff" android:pathData="M354,673L480,597L606,674L573,530L684,434L538,421L480,285L422,420L276,433L387,530L354,673ZM233,840L298,559L80,370L368,345L480,80L592,345L880,370L662,559L727,840L480,691L233,840ZM480,490L480,490L480,490L480,490L480,490L480,490L480,490L480,490L480,490L480,490Z"/> +</vector>
\ No newline at end of file diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 800f98d9a234..7ed52004d282 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -5888,6 +5888,7 @@ <java-symbol type="bool" name="config_deviceSupportsWifiUsd" /> <java-symbol type="array" name="config_notificationDefaultUnsupportedAdjustments" /> + <java-symbol type="drawable" name="ic_notification_summarization" /> <!-- Advanced Protection Service USB feature --> <java-symbol type="string" name="usb_apm_usb_plugged_in_when_locked_notification_title" /> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt index b6ef95893036..89cb42056e87 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt @@ -20,10 +20,17 @@ import android.app.Notification import android.app.Notification.EXTRA_SUMMARIZED_CONTENT import android.content.Context import android.content.pm.LauncherApps +import android.graphics.Typeface import android.graphics.drawable.AnimatedImageDrawable import android.os.Handler import android.service.notification.NotificationListenerService.Ranking import android.service.notification.NotificationListenerService.RankingMap +import android.text.SpannableString +import android.text.Spanned +import android.text.TextUtils +import android.text.style.ImageSpan +import android.text.style.StyleSpan +import com.android.internal.R import com.android.internal.widget.ConversationLayout import com.android.internal.widget.MessagingImageMessage import com.android.internal.widget.MessagingLayout @@ -49,6 +56,7 @@ import javax.inject.Inject class ConversationNotificationProcessor @Inject constructor( + @ShadeDisplayAware private val context: Context, private val launcherApps: LauncherApps, private val conversationNotificationManager: ConversationNotificationManager, ) { @@ -67,9 +75,38 @@ constructor( messagingStyle.shortcutIcon = launcherApps.getShortcutIcon(shortcutInfo) shortcutInfo.label?.let { label -> messagingStyle.conversationTitle = label } } - if (NmSummarizationUiFlag.isEnabled) { + if (NmSummarizationUiFlag.isEnabled && !TextUtils.isEmpty(entry.ranking.summarization)) { + val icon = context.getDrawable(R.drawable.ic_notification_summarization)?.mutate() + val imageSpan = + icon?.let { + it.setBounds( + /* left= */ 0, + /* top= */ 0, + icon.getIntrinsicWidth(), + icon.getIntrinsicHeight(), + ) + ImageSpan(it, ImageSpan.ALIGN_CENTER) + } + val decoratedSummary = + SpannableString("x" + entry.ranking.summarization).apply { + setSpan( + /* what = */ imageSpan, + /* start = */ 0, + /* end = */ 1, + /* flags = */ Spanned.SPAN_INCLUSIVE_EXCLUSIVE, + ) + entry.ranking.summarization?.let { + setSpan( + /* what = */ StyleSpan(Typeface.BOLD), + /* start = */ 1, + /* end = */ it.length, + /* flags = */ Spanned.SPAN_EXCLUSIVE_INCLUSIVE, + ) + } + } entry.sbn.notification.extras.putCharSequence( - EXTRA_SUMMARIZED_CONTENT, entry.ranking.summarization + EXTRA_SUMMARIZED_CONTENT, + decoratedSummary, ) } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridConversationNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridConversationNotificationView.java index 92c10abff735..344d0f6d3741 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridConversationNotificationView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridConversationNotificationView.java @@ -289,7 +289,7 @@ public class HybridConversationNotificationView extends HybridNotificationView { CharSequence titleText, CharSequence contentText, CharSequence conversationSenderName, - @Nullable String summarization + @Nullable CharSequence summarization ) { if (AsyncHybridViewInflation.isUnexpectedlyInLegacyMode()) return; if (summarization != null) { @@ -304,9 +304,8 @@ public class HybridConversationNotificationView extends HybridNotificationView { mConversationSenderName.setText(conversationSenderName); } } - // TODO (b/217799515): super.bind() doesn't use contentView, remove the contentView - // argument when the flag is removed - super.bind(/* title = */ titleText, /* text = */ contentText, /* contentView = */ null); + super.bind(/* title = */ titleText, /* text = */ contentText, + /* stripSpans = */ TextUtils.isEmpty(summarization)); } private static void setSize(View view, int size) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridNotificationView.java index 5c4c253d1f98..02dc805dcab4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridNotificationView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridNotificationView.java @@ -121,6 +121,11 @@ public class HybridNotificationView extends AlphaOptimizedLinearLayout public void bind(@Nullable CharSequence title, @Nullable CharSequence text, @Nullable View contentView) { + bind(/* title = */ title, /* text = */ text, /* stripSpans */ true); + } + + public void bind(@Nullable CharSequence title, @Nullable CharSequence text, + boolean stripSpans) { mTitleView.setText(title != null ? title.toString() : title); mTitleView.setVisibility(TextUtils.isEmpty(title) ? GONE : VISIBLE); if (TextUtils.isEmpty(text)) { @@ -128,7 +133,11 @@ public class HybridNotificationView extends AlphaOptimizedLinearLayout mTextView.setText(null); } else { mTextView.setVisibility(VISIBLE); - mTextView.setText(text.toString()); + if (stripSpans) { + mTextView.setText(text.toString()); + } else { + mTextView.setText(text); + } } requestLayout(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt index bc3653a34fca..20c3464536e9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt @@ -17,6 +17,7 @@ package com.android.systemui.statusbar.notification.row import android.annotation.SuppressLint import android.app.Notification +import android.app.Notification.EXTRA_SUMMARIZED_CONTENT import android.app.Notification.MessagingStyle import android.content.Context import android.content.ContextWrapper @@ -729,7 +730,9 @@ constructor( builder = builder, systemUiContext = systemUiContext, redactText = false, - summarization = entry.ranking.summarization, + summarization = entry.sbn.notification.extras.getCharSequence( + EXTRA_SUMMARIZED_CONTENT, + ) ) } else null diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/SingleLineViewInflater.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/SingleLineViewInflater.kt index c051513ef3b4..b3c8f2219f4d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/SingleLineViewInflater.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/SingleLineViewInflater.kt @@ -61,7 +61,7 @@ internal object SingleLineViewInflater { builder: Notification.Builder, systemUiContext: Context, redactText: Boolean, - summarization: String? + summarization: CharSequence? ): SingleLineViewModel { if (AsyncHybridViewInflation.isUnexpectedlyInLegacyMode()) { return SingleLineViewModel(null, null, null) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/SingleLineViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/SingleLineViewModel.kt index 32ded25f18a1..bb5cff98c470 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/SingleLineViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/SingleLineViewModel.kt @@ -46,7 +46,7 @@ data class SingleLineViewModel( data class ConversationData( val conversationSenderName: CharSequence?, val avatar: ConversationAvatar, - val summarization: String? + val summarization: CharSequence? ) /** diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowBuilder.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowBuilder.kt index e9c6c18550fb..e445a73b06d0 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowBuilder.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowBuilder.kt @@ -219,6 +219,7 @@ class ExpandableNotificationRowBuilder( } val conversationProcessor = ConversationNotificationProcessor( + context, Mockito.mock(LauncherApps::class.java, STUB_ONLY), Mockito.mock(ConversationNotificationManager::class.java, STUB_ONLY), ) |