summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java34
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/shared/model/PromotedNotificationContentModel.kt119
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/ActiveNotificationModel.kt22
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/model/ActiveNotificationModelBuilder.kt3
5 files changed, 186 insertions, 1 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
index e74ed8d27ec2..c487ff5d35bd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
@@ -49,6 +49,7 @@ import android.os.SystemClock;
import android.service.notification.NotificationListenerService.Ranking;
import android.service.notification.SnoozeCriterion;
import android.service.notification.StatusBarNotification;
+import android.util.Log;
import android.view.ContentInfo;
import androidx.annotation.NonNull;
@@ -65,6 +66,7 @@ import com.android.systemui.statusbar.notification.collection.notifcollection.No
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender;
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
import com.android.systemui.statusbar.notification.icon.IconPack;
+import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRowController;
import com.android.systemui.statusbar.notification.row.NotificationGuts;
@@ -194,6 +196,10 @@ public final class NotificationEntry extends ListEntry {
*/
private boolean mIsDemoted = false;
+ // TODO(b/377565433): Move into NotificationContentModel during/after
+ // NotificationRowContentBinderRefactor.
+ private PromotedNotificationContentModel mPromotedNotificationContentModel;
+
/**
* True if both
* 1) app provided full screen intent but does not have the permission to send it
@@ -1061,6 +1067,32 @@ public final class NotificationEntry extends ListEntry {
this.mHeadsUpStatusBarTextPublic.setValue(headsUpStatusBarModel.getPublicText());
}
+ /**
+ * Gets the content needed to render this notification as a promoted notification on various
+ * surfaces (like status bar chips and AOD).
+ */
+ public PromotedNotificationContentModel getPromotedNotificationContentModel() {
+ if (PromotedNotificationContentModel.featureFlagEnabled()) {
+ return mPromotedNotificationContentModel;
+ } else {
+ Log.wtf(TAG, "getting promoted content without feature flag enabled");
+ return null;
+ }
+ }
+
+ /**
+ * Sets the content needed to render this notification as a promoted notification on various
+ * surfaces (like status bar chips and AOD).
+ */
+ public void setPromotedNotificationContentModel(
+ @Nullable PromotedNotificationContentModel promotedNotificationContentModel) {
+ if (PromotedNotificationContentModel.featureFlagEnabled()) {
+ this.mPromotedNotificationContentModel = promotedNotificationContentModel;
+ } else {
+ Log.wtf(TAG, "setting promoted content without feature flag enabled");
+ }
+ }
+
/** Information about a suggestion that is being edited. */
public static class EditedSuggestionInfo {
@@ -1101,4 +1133,6 @@ public final class NotificationEntry extends ListEntry {
private static final long INITIALIZATION_DELAY = 400;
private static final long NOT_LAUNCHED_YET = -LAUNCH_COOLDOWN;
private static final int COLOR_INVALID = 1;
+
+ private static final String TAG = "NotificationEntry";
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt
index 23da90d426c7..8edbc5e8e4bb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt
@@ -34,6 +34,7 @@ import com.android.systemui.statusbar.notification.collection.provider.SectionSt
import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationListRepository
import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationsStore
import com.android.systemui.statusbar.notification.promoted.PromotedNotificationsProvider
+import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel
import com.android.systemui.statusbar.notification.shared.ActiveNotificationEntryModel
import com.android.systemui.statusbar.notification.shared.ActiveNotificationGroupModel
import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel
@@ -173,6 +174,7 @@ private class ActiveNotificationsStoreBuilder(
isGroupSummary = sbn.notification.isGroupSummary,
bucket = bucket,
callType = sbn.toCallType(),
+ promotedContent = promotedNotificationContentModel,
)
}
}
@@ -199,6 +201,7 @@ private fun ActiveNotificationsStore.createOrReuse(
isGroupSummary: Boolean,
bucket: Int,
callType: CallType,
+ promotedContent: PromotedNotificationContentModel?,
): ActiveNotificationModel {
return individuals[key]?.takeIf {
it.isCurrent(
@@ -223,6 +226,7 @@ private fun ActiveNotificationsStore.createOrReuse(
contentIntent = contentIntent,
bucket = bucket,
callType = callType,
+ promotedContent = promotedContent,
)
}
?: ActiveNotificationModel(
@@ -247,6 +251,7 @@ private fun ActiveNotificationsStore.createOrReuse(
contentIntent = contentIntent,
bucket = bucket,
callType = callType,
+ promotedContent = promotedContent,
)
}
@@ -272,6 +277,7 @@ private fun ActiveNotificationModel.isCurrent(
isGroupSummary: Boolean,
bucket: Int,
callType: CallType,
+ promotedContent: PromotedNotificationContentModel?,
): Boolean {
return when {
key != this.key -> false
@@ -295,6 +301,9 @@ private fun ActiveNotificationModel.isCurrent(
contentIntent != this.contentIntent -> false
bucket != this.bucket -> false
callType != this.callType -> false
+ // QQQ: Do we need to do the same `isCurrent` thing within the content model to avoid
+ // recreating the active notification model constantly?
+ promotedContent != this.promotedContent -> false
else -> true
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/shared/model/PromotedNotificationContentModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/shared/model/PromotedNotificationContentModel.kt
new file mode 100644
index 000000000000..41ee3b992c5a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/shared/model/PromotedNotificationContentModel.kt
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+
+package com.android.systemui.statusbar.notification.promoted.shared.model
+
+import android.annotation.DrawableRes
+import android.graphics.drawable.Icon
+import com.android.internal.widget.NotificationProgressModel
+import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips
+import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi
+
+/**
+ * The content needed to render a promoted notification to surfaces besides the notification stack,
+ * like the skeleton view on AOD or the status bar chip.
+ */
+data class PromotedNotificationContentModel(
+ val key: String,
+
+ // for all styles:
+ val skeletonSmallIcon: Icon?, // TODO(b/377568176): Make into an IconModel.
+ val appName: CharSequence?,
+ val subText: CharSequence?,
+ val time: When?,
+ val lastAudiblyAlertedMs: Long,
+ @DrawableRes val profileBadgeResId: Int?,
+ val title: CharSequence?,
+ val text: CharSequence?,
+ val skeletonLargeIcon: Icon?, // TODO(b/377568176): Make into an IconModel.
+ val style: Style,
+
+ // for CallStyle:
+ val personIcon: Icon?, // TODO(b/377568176): Make into an IconModel.
+ val personName: CharSequence?,
+ val verificationIcon: Icon?, // TODO(b/377568176): Make into an IconModel.
+ val verificationText: CharSequence?,
+
+ // for ProgressStyle:
+ val progress: NotificationProgressModel?,
+) {
+ class Builder(val key: String) {
+ var skeletonSmallIcon: Icon? = null
+ var appName: CharSequence? = null
+ var subText: CharSequence? = null
+ var time: When? = null
+ var lastAudiblyAlertedMs: Long = 0L
+ @DrawableRes var profileBadgeResId: Int? = null
+ var title: CharSequence? = null
+ var text: CharSequence? = null
+ var skeletonLargeIcon: Icon? = null
+ var style: Style = Style.Ineligible
+
+ // for CallStyle:
+ var personIcon: Icon? = null
+ var personName: CharSequence? = null
+ var verificationIcon: Icon? = null
+ var verificationText: CharSequence? = null
+
+ // for ProgressStyle:
+ var progress: NotificationProgressModel? = null
+
+ fun build() =
+ PromotedNotificationContentModel(
+ key = key,
+ skeletonSmallIcon = skeletonSmallIcon,
+ appName = appName,
+ subText = subText,
+ time = time,
+ lastAudiblyAlertedMs = lastAudiblyAlertedMs,
+ profileBadgeResId = profileBadgeResId,
+ title = title,
+ text = text,
+ skeletonLargeIcon = skeletonLargeIcon,
+ style = style,
+ personIcon = personIcon,
+ personName = personName,
+ verificationIcon = verificationIcon,
+ verificationText = verificationText,
+ progress = progress,
+ )
+ }
+
+ /** The timestamp associated with a notification, along with the mode used to display it. */
+ data class When(val time: Long, val mode: Mode) {
+ /** The mode used to display a notification's `when` value. */
+ enum class Mode {
+ Absolute,
+ CountDown,
+ CountUp,
+ }
+ }
+
+ /** The promotion-eligible style of a notification, or [Style.Ineligible] if not. */
+ enum class Style {
+ BigPicture,
+ BigText,
+ Call,
+ Progress,
+ Ineligible,
+ }
+
+ companion object {
+ @JvmStatic
+ fun featureFlagEnabled(): Boolean =
+ PromotedNotificationUi.isEnabled || StatusBarNotifChips.isEnabled
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/ActiveNotificationModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/ActiveNotificationModel.kt
index 19a92a2230ba..a2b71551eca8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/ActiveNotificationModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/ActiveNotificationModel.kt
@@ -17,7 +17,9 @@ package com.android.systemui.statusbar.notification.shared
import android.app.PendingIntent
import android.graphics.drawable.Icon
+import android.util.Log
import com.android.systemui.statusbar.StatusBarIconView
+import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel
import com.android.systemui.statusbar.notification.stack.PriorityBucket
/**
@@ -36,6 +38,7 @@ data class ActiveNotificationModel(
val groupKey: String?,
/** When this notification was posted. */
val whenTime: Long,
+ // TODO(b/377566661): Make isPromoted just check if promotedContent != null.
/** True if this notification should be promoted and false otherwise. */
val isPromoted: Boolean,
/** Is this entry in the ambient / minimized section (lowest priority)? */
@@ -78,7 +81,24 @@ data class ActiveNotificationModel(
@PriorityBucket val bucket: Int,
/** The call type set on the notification. */
val callType: CallType,
-) : ActiveNotificationEntryModel()
+ /**
+ * The content needed to render this as a promoted notification on various surfaces, or null if
+ * this notification cannot be rendered as a promoted notification.
+ */
+ val promotedContent: PromotedNotificationContentModel?,
+) : ActiveNotificationEntryModel() {
+ init {
+ if (!PromotedNotificationContentModel.featureFlagEnabled()) {
+ if (promotedContent != null) {
+ Log.wtf(TAG, "passing non-null promoted content without feature flag enabled")
+ }
+ }
+ }
+
+ companion object {
+ private const val TAG = "ActiveNotificationEntryModel"
+ }
+}
/** Model for a group of notifications. */
data class ActiveNotificationGroupModel(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/model/ActiveNotificationModelBuilder.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/model/ActiveNotificationModelBuilder.kt
index 32c582f79ed7..2ec801620212 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/model/ActiveNotificationModelBuilder.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/model/ActiveNotificationModelBuilder.kt
@@ -19,6 +19,7 @@ package com.android.systemui.statusbar.notification.data.model
import android.app.PendingIntent
import android.graphics.drawable.Icon
import com.android.systemui.statusbar.StatusBarIconView
+import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel
import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel
import com.android.systemui.statusbar.notification.shared.CallType
import com.android.systemui.statusbar.notification.stack.BUCKET_UNKNOWN
@@ -46,6 +47,7 @@ fun activeNotificationModel(
contentIntent: PendingIntent? = null,
bucket: Int = BUCKET_UNKNOWN,
callType: CallType = CallType.None,
+ promotedContent: PromotedNotificationContentModel? = null,
) =
ActiveNotificationModel(
key = key,
@@ -69,4 +71,5 @@ fun activeNotificationModel(
isGroupSummary = isGroupSummary,
bucket = bucket,
callType = callType,
+ promotedContent = promotedContent,
)