Merge "When applying a RankingMap that lacks an entry, remove that entry from the NotifCollection." into tm-qpr-dev am: c6701d965b

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/18366674

Change-Id: I82c701a3b9edce5324a6276a67f8d61e903e3f69
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Jeff DeCew
2022-06-27 11:24:02 +00:00
committed by Automerger Merge Worker
5 changed files with 92 additions and 1 deletions

View File

@@ -60,6 +60,9 @@ public class Flags {
public static final ResourceBooleanFlag NOTIFICATION_DRAG_TO_CONTENTS = public static final ResourceBooleanFlag NOTIFICATION_DRAG_TO_CONTENTS =
new ResourceBooleanFlag(108, R.bool.config_notificationToContents); new ResourceBooleanFlag(108, R.bool.config_notificationToContents);
public static final BooleanFlag REMOVE_UNRANKED_NOTIFICATIONS =
new BooleanFlag(109, false);
/***************************************/ /***************************************/
// 200 - keyguard/lockscreen // 200 - keyguard/lockscreen

View File

@@ -56,4 +56,7 @@ class NotifPipelineFlags @Inject constructor(
fun isSmartspaceDedupingEnabled(): Boolean = fun isSmartspaceDedupingEnabled(): Boolean =
featureFlags.isEnabled(Flags.SMARTSPACE) && featureFlags.isEnabled(Flags.SMARTSPACE) &&
featureFlags.isEnabled(Flags.SMARTSPACE_DEDUPING) featureFlags.isEnabled(Flags.SMARTSPACE_DEDUPING)
}
fun removeUnrankedNotifs(): Boolean =
featureFlags.isEnabled(Flags.REMOVE_UNRANKED_NOTIFICATIONS)
}

View File

@@ -601,6 +601,12 @@ public class NotifCollection implements Dumpable {
); );
mNotificationsWithoutRankings = currentEntriesWithoutRankings == null mNotificationsWithoutRankings = currentEntriesWithoutRankings == null
? Collections.emptySet() : currentEntriesWithoutRankings.keySet(); ? Collections.emptySet() : currentEntriesWithoutRankings.keySet();
if (currentEntriesWithoutRankings != null && mNotifPipelineFlags.removeUnrankedNotifs()) {
for (NotificationEntry entry : currentEntriesWithoutRankings.values()) {
entry.mCancellationReason = REASON_UNKNOWN;
tryRemoveNotification(entry);
}
}
mEventQueue.add(new RankingAppliedEvent()); mEventQueue.add(new RankingAppliedEvent());
} }

View File

@@ -85,6 +85,11 @@ public class NoManSimulator {
mRankings.put(key, ranking); mRankings.put(key, ranking);
} }
/** This is for testing error cases: b/216384850 */
public Ranking removeRankingWithoutEvent(String key) {
return mRankings.remove(key);
}
private RankingMap buildRankingMap() { private RankingMap buildRankingMap() {
return new RankingMap(mRankings.values().toArray(new Ranking[0])); return new RankingMap(mRankings.values().toArray(new Ranking[0]));
} }

View File

@@ -1491,6 +1491,80 @@ public class NotifCollectionTest extends SysuiTestCase {
verify(mCollectionListener, never()).onEntryUpdated(any(), anyBoolean()); verify(mCollectionListener, never()).onEntryUpdated(any(), anyBoolean());
} }
@Test
public void testMissingRankingWhenRemovalFeatureIsDisabled() {
// GIVEN a pipeline with one two notifications
when(mNotifPipelineFlags.removeUnrankedNotifs()).thenReturn(false);
String key1 = mNoMan.postNotif(buildNotif(TEST_PACKAGE, 1, "myTag")).key;
String key2 = mNoMan.postNotif(buildNotif(TEST_PACKAGE, 2, "myTag")).key;
NotificationEntry entry1 = mCollectionListener.getEntry(key1);
NotificationEntry entry2 = mCollectionListener.getEntry(key2);
clearInvocations(mCollectionListener);
// GIVEN the message for removing key1 gets does not reach NotifCollection
Ranking ranking1 = mNoMan.removeRankingWithoutEvent(key1);
// WHEN the message for removing key2 arrives
mNoMan.retractNotif(entry2.getSbn(), REASON_APP_CANCEL);
// THEN only entry2 gets removed
verify(mCollectionListener).onEntryRemoved(eq(entry2), eq(REASON_APP_CANCEL));
verify(mCollectionListener).onEntryCleanUp(eq(entry2));
verify(mCollectionListener).onRankingApplied();
verifyNoMoreInteractions(mCollectionListener);
verify(mLogger).logMissingRankings(eq(List.of(entry1)), eq(1), any());
verify(mLogger, never()).logRecoveredRankings(any());
clearInvocations(mCollectionListener, mLogger);
// WHEN a ranking update includes key1 again
mNoMan.setRanking(key1, ranking1);
mNoMan.issueRankingUpdate();
// VERIFY that we do nothing but log the 'recovery'
verify(mCollectionListener).onRankingUpdate(any());
verify(mCollectionListener).onRankingApplied();
verifyNoMoreInteractions(mCollectionListener);
verify(mLogger, never()).logMissingRankings(any(), anyInt(), any());
verify(mLogger).logRecoveredRankings(eq(List.of(key1)));
}
@Test
public void testMissingRankingWhenRemovalFeatureIsEnabled() {
// GIVEN a pipeline with one two notifications
when(mNotifPipelineFlags.removeUnrankedNotifs()).thenReturn(true);
String key1 = mNoMan.postNotif(buildNotif(TEST_PACKAGE, 1, "myTag")).key;
String key2 = mNoMan.postNotif(buildNotif(TEST_PACKAGE, 2, "myTag")).key;
NotificationEntry entry1 = mCollectionListener.getEntry(key1);
NotificationEntry entry2 = mCollectionListener.getEntry(key2);
clearInvocations(mCollectionListener);
// GIVEN the message for removing key1 gets does not reach NotifCollection
Ranking ranking1 = mNoMan.removeRankingWithoutEvent(key1);
// WHEN the message for removing key2 arrives
mNoMan.retractNotif(entry2.getSbn(), REASON_APP_CANCEL);
// THEN both entry1 and entry2 get removed
verify(mCollectionListener).onEntryRemoved(eq(entry2), eq(REASON_APP_CANCEL));
verify(mCollectionListener).onEntryRemoved(eq(entry1), eq(REASON_UNKNOWN));
verify(mCollectionListener).onEntryCleanUp(eq(entry2));
verify(mCollectionListener).onEntryCleanUp(eq(entry1));
verify(mCollectionListener).onRankingApplied();
verifyNoMoreInteractions(mCollectionListener);
verify(mLogger).logMissingRankings(eq(List.of(entry1)), eq(1), any());
verify(mLogger, never()).logRecoveredRankings(any());
clearInvocations(mCollectionListener, mLogger);
// WHEN a ranking update includes key1 again
mNoMan.setRanking(key1, ranking1);
mNoMan.issueRankingUpdate();
// VERIFY that we do nothing but log the 'recovery'
verify(mCollectionListener).onRankingUpdate(any());
verify(mCollectionListener).onRankingApplied();
verifyNoMoreInteractions(mCollectionListener);
verify(mLogger, never()).logMissingRankings(any(), anyInt(), any());
verify(mLogger).logRecoveredRankings(eq(List.of(key1)));
}
@Test @Test
public void testRegisterFutureDismissal() throws RemoteException { public void testRegisterFutureDismissal() throws RemoteException {
// GIVEN a pipeline with one notification // GIVEN a pipeline with one notification