Lazy async group notification views inflation
Use the result of the notification pipeline grouping to inflate the single-line and group summary views instead of the grouping status of status bar notification. This change can reduce the views to inflate to optimize memory usage.
Bug: 217799515
Test: atest NotifUiAdjustmentProviderTest
Flag: ACONFIG notification_async_hybrid_view_inflation STAGING
ACONFIG notification_async_group_header_inflation DEVELOPMENT
Change-Id: If33f4862b540754dc67651b06f5fa354fb23aa8c
diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java
index d821074..264b53c 100644
--- a/core/java/android/service/notification/StatusBarNotification.java
+++ b/core/java/android/service/notification/StatusBarNotification.java
@@ -174,23 +174,6 @@
return sbnKey;
}
- /**
- * @return Whether the Entry is a group child by the app or system
- * @hide
- */
- public boolean isAppOrSystemGroupChild() {
- return isGroup() && !getNotification().isGroupSummary();
- }
-
-
- /**
- * @return Whether the Entry is a group summary by the app or system
- * @hide
- */
- public boolean isAppOrSystemGroupSummary() {
- return isGroup() && getNotification().isGroupSummary();
- }
-
private String groupKey() {
if (overrideGroupKey != null) {
return user.getIdentifier() + "|" + pkg + "|" + "g:" + overrideGroupKey;
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 8cdf60b..c1dd992 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
@@ -171,6 +171,9 @@
private boolean mIsMarkedForUserTriggeredMovement;
private boolean mIsHeadsUpEntry;
+ private boolean mHasEverBeenGroupSummary;
+ private boolean mHasEverBeenGroupChild;
+
public boolean mRemoteEditImeAnimatingAway;
public boolean mRemoteEditImeVisible;
private boolean mExpandAnimationRunning;
@@ -217,6 +220,26 @@
mIsDemoted = true;
}
+ /** called when entry is currently a summary of a group */
+ public void markAsGroupSummary() {
+ mHasEverBeenGroupSummary = true;
+ }
+
+ /** whether this entry has ever been marked as a summary */
+ public boolean hasEverBeenGroupSummary() {
+ return mHasEverBeenGroupSummary;
+ }
+
+ /** called when entry is currently a child in a group */
+ public void markAsGroupChild() {
+ mHasEverBeenGroupChild = true;
+ }
+
+ /** whether this entry has ever been marked as a child */
+ public boolean hasEverBeenGroupChild() {
+ return mHasEverBeenGroupChild;
+ }
+
/**
* @param sbn the StatusBarNotification from system server
* @param ranking also from system server
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java
index 7a7b184..9b075a6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java
@@ -49,6 +49,8 @@
import com.android.systemui.statusbar.notification.collection.render.NotifViewController;
import com.android.systemui.statusbar.notification.row.NotifInflationErrorManager;
import com.android.systemui.statusbar.notification.row.NotifInflationErrorManager.NotifInflationErrorListener;
+import com.android.systemui.statusbar.notification.row.shared.AsyncGroupHeaderViewInflation;
+import com.android.systemui.statusbar.notification.row.shared.AsyncHybridViewInflation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -273,10 +275,14 @@
private void inflateRequiredGroupViews(GroupEntry groupEntry) {
NotificationEntry summary = groupEntry.getSummary();
+ if (summary != null && AsyncGroupHeaderViewInflation.isEnabled()) {
+ summary.markAsGroupSummary();
+ }
List<NotificationEntry> children = groupEntry.getChildren();
inflateRequiredNotifViews(summary);
for (int j = 0; j < children.size(); j++) {
NotificationEntry child = children.get(j);
+ if (AsyncHybridViewInflation.isEnabled()) child.markAsGroupChild();
boolean childShouldBeBound = j < mChildBindCutoff;
if (childShouldBeBound) {
inflateRequiredNotifViews(child);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustment.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustment.kt
index bab94b5..e70fb6b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustment.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustment.kt
@@ -52,11 +52,8 @@
oldAdjustment.needsRedaction != newAdjustment.needsRedaction -> true
areDifferent(oldAdjustment.smartActions, newAdjustment.smartActions) -> true
newAdjustment.smartReplies != oldAdjustment.smartReplies -> true
- // TODO(b/217799515): Here we decide whether to re-inflate the row on every group-status
- // change if we want to keep the single-line view, the following line should be:
- // !oldAdjustment.isChildInGroup && newAdjustment.isChildInGroup -> true
AsyncHybridViewInflation.isEnabled &&
- oldAdjustment.isChildInGroup != newAdjustment.isChildInGroup -> true
+ !oldAdjustment.isChildInGroup && newAdjustment.isChildInGroup -> true
AsyncGroupHeaderViewInflation.isEnabled &&
!oldAdjustment.isGroupSummary && newAdjustment.isGroupSummary -> true
else -> false
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProvider.kt
index e0e5a35..4c2ef83 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProvider.kt
@@ -141,7 +141,7 @@
lockscreenUserManager.needsRedaction(entry) ||
(screenshareNotificationHiding() &&
sensitiveNotifProtectionController.shouldProtectNotification(entry)),
- isChildInGroup = entry.sbn.isAppOrSystemGroupChild,
- isGroupSummary = entry.sbn.isAppOrSystemGroupSummary,
+ isChildInGroup = entry.hasEverBeenGroupChild(),
+ isGroupSummary = entry.hasEverBeenGroupSummary(),
)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProviderTest.kt
index 34eeba0..8e6cecc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProviderTest.kt
@@ -49,7 +49,6 @@
import org.junit.runner.RunWith
import org.mockito.Mockito.clearInvocations
import org.mockito.Mockito.inOrder
-import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyNoMoreInteractions
import org.mockito.Mockito.`when` as whenever
@@ -158,17 +157,14 @@
@Test
@EnableFlags(AsyncHybridViewInflation.FLAG_NAME)
- fun changeIsChildInGroup_asyncHybirdFlagEnabled_needReInflation() {
+ fun becomeChildInGroup_asyncHybirdFlagEnabled_needReInflation() {
// Given: an Entry that is not child in group
// AsyncHybridViewInflation flag is enabled
- val spySbn = spy(entry.sbn)
- entry.sbn = spySbn
- whenever(spySbn.isAppOrSystemGroupChild).thenReturn(false)
val oldAdjustment = adjustmentProvider.calculateAdjustment(entry)
assertThat(oldAdjustment.isChildInGroup).isFalse()
// When: the Entry becomes a group child
- whenever(spySbn.isAppOrSystemGroupChild).thenReturn(true)
+ entry.markAsGroupChild()
val newAdjustment = adjustmentProvider.calculateAdjustment(entry)
assertThat(newAdjustment.isChildInGroup).isTrue()
assertThat(newAdjustment).isNotEqualTo(oldAdjustment)
@@ -179,17 +175,14 @@
@Test
@DisableFlags(AsyncHybridViewInflation.FLAG_NAME)
- fun changeIsChildInGroup_asyncHybirdFlagDisabled_noNeedForReInflation() {
+ fun becomeChildInGroup_asyncHybirdFlagDisabled_noNeedForReInflation() {
// Given: an Entry that is not child in group
// AsyncHybridViewInflation flag is disabled
- val spySbn = spy(entry.sbn)
- entry.sbn = spySbn
- whenever(spySbn.isAppOrSystemGroupChild).thenReturn(false)
val oldAdjustment = adjustmentProvider.calculateAdjustment(entry)
assertThat(oldAdjustment.isChildInGroup).isFalse()
// When: the Entry becomes a group child
- whenever(spySbn.isAppOrSystemGroupChild).thenReturn(true)
+ entry.markAsGroupChild()
val newAdjustment = adjustmentProvider.calculateAdjustment(entry)
assertThat(newAdjustment.isChildInGroup).isTrue()
assertThat(newAdjustment).isNotEqualTo(oldAdjustment)
@@ -202,14 +195,11 @@
@EnableFlags(AsyncGroupHeaderViewInflation.FLAG_NAME)
fun changeIsGroupSummary_needReInflation() {
// Given: an Entry that is not a group summary
- val spySbn = spy(entry.sbn)
- entry.sbn = spySbn
- whenever(spySbn.isAppOrSystemGroupSummary).thenReturn(false)
val oldAdjustment = adjustmentProvider.calculateAdjustment(entry)
assertThat(oldAdjustment.isGroupSummary).isFalse()
// When: the Entry becomes a group summary
- whenever(spySbn.isAppOrSystemGroupSummary).thenReturn(true)
+ entry.markAsGroupSummary()
val newAdjustment = adjustmentProvider.calculateAdjustment(entry)
assertThat(newAdjustment.isGroupSummary).isTrue()
assertThat(newAdjustment).isNotEqualTo(oldAdjustment)