Loading core/java/android/service/notification/NotificationListenerService.java +192 −388 File changed.Preview size limit exceeded, changes collapsed. Show changes core/java/android/service/notification/NotificationRankingUpdate.java +18 −154 Original line number Diff line number Diff line Loading @@ -15,7 +15,6 @@ */ package android.service.notification; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; Loading @@ -23,73 +22,18 @@ import android.os.Parcelable; * @hide */ public class NotificationRankingUpdate implements Parcelable { // TODO: Support incremental updates. private final String[] mKeys; private final String[] mInterceptedKeys; private final Bundle mVisibilityOverrides; private final Bundle mSuppressedVisualEffects; private final int[] mImportance; private final Bundle mImportanceExplanation; private final Bundle mOverrideGroupKeys; private final Bundle mChannels; private final Bundle mOverridePeople; private final Bundle mSnoozeCriteria; private final Bundle mShowBadge; private final Bundle mUserSentiment; private final Bundle mHidden; private final Bundle mSmartActions; private final Bundle mSmartReplies; private final Bundle mLastAudiblyAlerted; private final Bundle mNoisy; private final boolean[] mCanBubble; private final NotificationListenerService.RankingMap mRankingMap; public NotificationRankingUpdate(String[] keys, String[] interceptedKeys, Bundle visibilityOverrides, Bundle suppressedVisualEffects, int[] importance, Bundle explanation, Bundle overrideGroupKeys, Bundle channels, Bundle overridePeople, Bundle snoozeCriteria, Bundle showBadge, Bundle userSentiment, Bundle hidden, Bundle smartActions, Bundle smartReplies, Bundle lastAudiblyAlerted, Bundle noisy, boolean[] canBubble) { mKeys = keys; mInterceptedKeys = interceptedKeys; mVisibilityOverrides = visibilityOverrides; mSuppressedVisualEffects = suppressedVisualEffects; mImportance = importance; mImportanceExplanation = explanation; mOverrideGroupKeys = overrideGroupKeys; mChannels = channels; mOverridePeople = overridePeople; mSnoozeCriteria = snoozeCriteria; mShowBadge = showBadge; mUserSentiment = userSentiment; mHidden = hidden; mSmartActions = smartActions; mSmartReplies = smartReplies; mLastAudiblyAlerted = lastAudiblyAlerted; mNoisy = noisy; mCanBubble = canBubble; public NotificationRankingUpdate(NotificationListenerService.Ranking[] rankings) { mRankingMap = new NotificationListenerService.RankingMap(rankings); } public NotificationRankingUpdate(Parcel in) { mKeys = in.readStringArray(); mInterceptedKeys = in.readStringArray(); mVisibilityOverrides = in.readBundle(); mSuppressedVisualEffects = in.readBundle(); mImportance = new int[mKeys.length]; in.readIntArray(mImportance); mImportanceExplanation = in.readBundle(); mOverrideGroupKeys = in.readBundle(); mChannels = in.readBundle(); mOverridePeople = in.readBundle(); mSnoozeCriteria = in.readBundle(); mShowBadge = in.readBundle(); mUserSentiment = in.readBundle(); mHidden = in.readBundle(); mSmartActions = in.readBundle(); mSmartReplies = in.readBundle(); mLastAudiblyAlerted = in.readBundle(); mNoisy = in.readBundle(); mCanBubble = new boolean[mKeys.length]; in.readBooleanArray(mCanBubble); mRankingMap = in.readParcelable(getClass().getClassLoader()); } public NotificationListenerService.RankingMap getRankingMap() { return mRankingMap; } @Override Loading @@ -97,26 +41,18 @@ public class NotificationRankingUpdate implements Parcelable { return 0; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; NotificationRankingUpdate other = (NotificationRankingUpdate) o; return mRankingMap.equals(other.mRankingMap); } @Override public void writeToParcel(Parcel out, int flags) { out.writeStringArray(mKeys); out.writeStringArray(mInterceptedKeys); out.writeBundle(mVisibilityOverrides); out.writeBundle(mSuppressedVisualEffects); out.writeIntArray(mImportance); out.writeBundle(mImportanceExplanation); out.writeBundle(mOverrideGroupKeys); out.writeBundle(mChannels); out.writeBundle(mOverridePeople); out.writeBundle(mSnoozeCriteria); out.writeBundle(mShowBadge); out.writeBundle(mUserSentiment); out.writeBundle(mHidden); out.writeBundle(mSmartActions); out.writeBundle(mSmartReplies); out.writeBundle(mLastAudiblyAlerted); out.writeBundle(mNoisy); out.writeBooleanArray(mCanBubble); out.writeParcelable(mRankingMap, flags); } public static final @android.annotation.NonNull Parcelable.Creator<NotificationRankingUpdate> CREATOR Loading @@ -129,76 +65,4 @@ public class NotificationRankingUpdate implements Parcelable { return new NotificationRankingUpdate[size]; } }; public String[] getOrderedKeys() { return mKeys; } public String[] getInterceptedKeys() { return mInterceptedKeys; } public Bundle getVisibilityOverrides() { return mVisibilityOverrides; } public Bundle getSuppressedVisualEffects() { return mSuppressedVisualEffects; } public int[] getImportance() { return mImportance; } public Bundle getImportanceExplanation() { return mImportanceExplanation; } public Bundle getOverrideGroupKeys() { return mOverrideGroupKeys; } public Bundle getChannels() { return mChannels; } public Bundle getOverridePeople() { return mOverridePeople; } public Bundle getSnoozeCriteria() { return mSnoozeCriteria; } public Bundle getShowBadge() { return mShowBadge; } public Bundle getUserSentiment() { return mUserSentiment; } public Bundle getHidden() { return mHidden; } public Bundle getSmartActions() { return mSmartActions; } public Bundle getSmartReplies() { return mSmartReplies; } public Bundle getLastAudiblyAlerted() { return mLastAudiblyAlerted; } public Bundle getNoisy() { return mNoisy; } public boolean[] getCanBubble() { return mCanBubble; } } services/core/java/com/android/server/notification/NotificationManagerService.java +30 −60 Original line number Diff line number Diff line Loading @@ -7234,72 +7234,42 @@ public class NotificationManagerService extends SystemService { @GuardedBy("mNotificationLock") private NotificationRankingUpdate makeRankingUpdateLocked(ManagedServiceInfo info) { final int N = mNotificationList.size(); ArrayList<String> keys = new ArrayList<String>(N); ArrayList<String> interceptedKeys = new ArrayList<String>(N); ArrayList<Integer> importance = new ArrayList<>(N); Bundle overrideGroupKeys = new Bundle(); Bundle visibilityOverrides = new Bundle(); Bundle suppressedVisualEffects = new Bundle(); Bundle explanation = new Bundle(); Bundle channels = new Bundle(); Bundle overridePeople = new Bundle(); Bundle snoozeCriteria = new Bundle(); Bundle showBadge = new Bundle(); Bundle userSentiment = new Bundle(); Bundle hidden = new Bundle(); Bundle systemGeneratedSmartActions = new Bundle(); Bundle smartReplies = new Bundle(); Bundle lastAudiblyAlerted = new Bundle(); Bundle noisy = new Bundle(); ArrayList<Boolean> canBubble = new ArrayList<>(N); final ArrayList<NotificationListenerService.Ranking> rankings = new ArrayList<>(); for (int i = 0; i < N; i++) { NotificationRecord record = mNotificationList.get(i); if (!isVisibleToListener(record.sbn, info)) { continue; } final String key = record.sbn.getKey(); keys.add(key); importance.add(record.getImportance()); if (record.getImportanceExplanation() != null) { explanation.putCharSequence(key, record.getImportanceExplanation()); } if (record.isIntercepted()) { interceptedKeys.add(key); } suppressedVisualEffects.putInt(key, record.getSuppressedVisualEffects()); if (record.getPackageVisibilityOverride() != NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE) { visibilityOverrides.putInt(key, record.getPackageVisibilityOverride()); } overrideGroupKeys.putString(key, record.sbn.getOverrideGroupKey()); channels.putParcelable(key, record.getChannel()); overridePeople.putStringArrayList(key, record.getPeopleOverride()); snoozeCriteria.putParcelableArrayList(key, record.getSnoozeCriteria()); showBadge.putBoolean(key, record.canShowBadge()); userSentiment.putInt(key, record.getUserSentiment()); hidden.putBoolean(key, record.isHidden()); systemGeneratedSmartActions.putParcelableArrayList(key, record.getSystemGeneratedSmartActions()); smartReplies.putCharSequenceArrayList(key, record.getSmartReplies()); lastAudiblyAlerted.putLong(key, record.getLastAudiblyAlertedMs()); noisy.putBoolean(key, record.getSound() != null || record.getVibration() != null); canBubble.add(record.canBubble()); } final int M = keys.size(); String[] keysAr = keys.toArray(new String[M]); String[] interceptedKeysAr = interceptedKeys.toArray(new String[interceptedKeys.size()]); int[] importanceAr = new int[M]; boolean[] canBubbleAr = new boolean[M]; for (int i = 0; i < M; i++) { importanceAr[i] = importance.get(i); canBubbleAr[i] = canBubble.get(i); } return new NotificationRankingUpdate(keysAr, interceptedKeysAr, visibilityOverrides, suppressedVisualEffects, importanceAr, explanation, overrideGroupKeys, channels, overridePeople, snoozeCriteria, showBadge, userSentiment, hidden, systemGeneratedSmartActions, smartReplies, lastAudiblyAlerted, noisy, canBubbleAr); final NotificationListenerService.Ranking ranking = new NotificationListenerService.Ranking(); ranking.populate( key, rankings.size(), !record.isIntercepted(), record.getPackageVisibilityOverride(), record.getSuppressedVisualEffects(), record.getImportance(), record.getImportanceExplanation(), record.sbn.getOverrideGroupKey(), record.getChannel(), record.getPeopleOverride(), record.getSnoozeCriteria(), record.canShowBadge(), record.getUserSentiment(), record.isHidden(), record.getLastAudiblyAlertedMs(), record.getSound() != null || record.getVibration() != null, record.getSystemGeneratedSmartActions(), record.getSmartReplies(), record.canBubble() ); rankings.add(ranking); } return new NotificationRankingUpdate( rankings.toArray(new NotificationListenerService.Ranking[0])); } boolean hasCompanionDevice(ManagedServiceInfo info) { Loading services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java +139 −46 Original line number Diff line number Diff line Loading @@ -20,7 +20,9 @@ import static android.service.notification.NotificationListenerService.Ranking.U import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL; import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_POSITIVE; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; Loading @@ -33,10 +35,11 @@ import android.app.NotificationChannel; import android.app.PendingIntent; import android.content.Intent; import android.os.Binder; import android.os.Bundle; import android.os.IBinder; import android.os.Parcel; import android.service.notification.NotificationListenerService; import android.service.notification.NotificationListenerService.Ranking; import android.service.notification.NotificationListenerService.RankingMap; import android.service.notification.NotificationRankingUpdate; import android.service.notification.SnoozeCriterion; import android.test.suitebuilder.annotation.SmallTest; Loading @@ -55,8 +58,6 @@ import java.util.List; @RunWith(AndroidJUnit4.class) public class NotificationListenerServiceTest extends UiServiceTestCase { private String[] mKeys = new String[] { "key", "key1", "key2", "key3", "key4"}; @Test public void testGetActiveNotifications_notNull() throws Exception { TestListenerService service = new TestListenerService(); Loading Loading @@ -97,52 +98,144 @@ public class NotificationListenerServiceTest extends UiServiceTestCase { } } private NotificationRankingUpdate generateUpdate() { List<String> interceptedKeys = new ArrayList<>(); Bundle visibilityOverrides = new Bundle(); Bundle overrideGroupKeys = new Bundle(); Bundle suppressedVisualEffects = new Bundle(); Bundle explanation = new Bundle(); Bundle channels = new Bundle(); Bundle overridePeople = new Bundle(); Bundle snoozeCriteria = new Bundle(); Bundle showBadge = new Bundle(); int[] importance = new int[mKeys.length]; Bundle userSentiment = new Bundle(); Bundle mHidden = new Bundle(); Bundle smartActions = new Bundle(); Bundle smartReplies = new Bundle(); Bundle lastAudiblyAlerted = new Bundle(); Bundle noisy = new Bundle(); boolean[] canBubble = new boolean[mKeys.length]; // Tests parceling of NotificationRankingUpdate, and by extension, RankingMap and Ranking. @Test public void testRankingUpdate_parcel() { NotificationRankingUpdate nru = generateUpdate(); Parcel parcel = Parcel.obtain(); nru.writeToParcel(parcel, 0); parcel.setDataPosition(0); NotificationRankingUpdate nru1 = NotificationRankingUpdate.CREATOR.createFromParcel(parcel); assertEquals(nru, nru1); } private void detailedAssertEquals(RankingMap a, RankingMap b) { Ranking arank = new Ranking(); Ranking brank = new Ranking(); assertArrayEquals(a.getOrderedKeys(), b.getOrderedKeys()); for (String key : a.getOrderedKeys()) { a.getRanking(key, arank); b.getRanking(key, brank); detailedAssertEquals("ranking for key <" + key + ">", arank, brank); } } // Tests parceling of RankingMap and RankingMap.equals @Test public void testRankingMap_parcel() { RankingMap rmap = generateUpdate().getRankingMap(); Parcel parcel = Parcel.obtain(); rmap.writeToParcel(parcel, 0); parcel.setDataPosition(0); RankingMap rmap1 = RankingMap.CREATOR.createFromParcel(parcel); detailedAssertEquals(rmap, rmap1); assertEquals(rmap, rmap1); } private void detailedAssertEquals(String comment, Ranking a, Ranking b) { assertEquals(comment, a.getKey(), b.getKey()); assertEquals(comment, a.getRank(), b.getRank()); assertEquals(comment, a.matchesInterruptionFilter(), b.matchesInterruptionFilter()); assertEquals(comment, a.getVisibilityOverride(), b.getVisibilityOverride()); assertEquals(comment, a.getSuppressedVisualEffects(), b.getSuppressedVisualEffects()); assertEquals(comment, a.getImportance(), b.getImportance()); assertEquals(comment, a.getImportanceExplanation(), b.getImportanceExplanation()); assertEquals(comment, a.getOverrideGroupKey(), b.getOverrideGroupKey()); assertEquals(comment, a.getChannel(), b.getChannel()); assertEquals(comment, a.getAdditionalPeople(), b.getAdditionalPeople()); assertEquals(comment, a.getSnoozeCriteria(), b.getSnoozeCriteria()); assertEquals(comment, a.canShowBadge(), b.canShowBadge()); assertEquals(comment, a.getUserSentiment(), b.getUserSentiment()); assertEquals(comment, a.isSuspended(), b.isSuspended()); assertEquals(comment, a.getLastAudiblyAlertedMillis(), b.getLastAudiblyAlertedMillis()); assertEquals(comment, a.isNoisy(), b.isNoisy()); assertEquals(comment, a.getSmartReplies(), b.getSmartReplies()); assertEquals(comment, a.canBubble(), b.canBubble()); assertActionsEqual(a.getSmartActions(), b.getSmartActions()); } // Tests parceling of Ranking and Ranking.equals @Test public void testRanking_parcel() { Ranking ranking = generateUpdate().getRankingMap().getRawRankingObject(mKeys[0]); Parcel parcel = Parcel.obtain(); ranking.writeToParcel(parcel, 0); parcel.setDataPosition(0); Ranking ranking1 = new Ranking(parcel); detailedAssertEquals("rankings differ: ", ranking, ranking1); assertEquals(ranking, ranking1); } private void detailedAssertEquals(NotificationRankingUpdate a, NotificationRankingUpdate b) { assertEquals(a.getRankingMap(), b.getRankingMap()); } // Tests NotificationRankingUpdate.equals(), and by extension, RankingMap and Ranking. @Test public void testRankingUpdate_equals() { NotificationRankingUpdate nru = generateUpdate(); NotificationRankingUpdate nru2 = generateUpdate(); detailedAssertEquals(nru, nru2); assertEquals(nru, nru2); Ranking tweak = nru2.getRankingMap().getRawRankingObject(mKeys[0]); tweak.populate( tweak.getKey(), tweak.getRank(), !tweak.matchesInterruptionFilter(), // note the inversion here! tweak.getVisibilityOverride(), tweak.getSuppressedVisualEffects(), tweak.getImportance(), tweak.getImportanceExplanation(), tweak.getOverrideGroupKey(), tweak.getChannel(), (ArrayList) tweak.getAdditionalPeople(), (ArrayList) tweak.getSnoozeCriteria(), tweak.canShowBadge(), tweak.getUserSentiment(), tweak.isSuspended(), tweak.getLastAudiblyAlertedMillis(), tweak.isNoisy(), (ArrayList) tweak.getSmartActions(), (ArrayList) tweak.getSmartReplies(), tweak.canBubble() ); assertNotEquals(nru, nru2); } // Test data private String[] mKeys = new String[] { "key", "key1", "key2", "key3", "key4"}; private NotificationRankingUpdate generateUpdate() { Ranking[] rankings = new Ranking[mKeys.length]; for (int i = 0; i < mKeys.length; i++) { String key = mKeys[i]; visibilityOverrides.putInt(key, getVisibilityOverride(i)); overrideGroupKeys.putString(key, getOverrideGroupKey(key)); if (isIntercepted(i)) { interceptedKeys.add(key); } suppressedVisualEffects.putInt(key, getSuppressedVisualEffects(i)); importance[i] = getImportance(i); explanation.putString(key, getExplanation(key)); channels.putParcelable(key, getChannel(key, i)); overridePeople.putStringArrayList(key, getPeople(key, i)); snoozeCriteria.putParcelableArrayList(key, getSnoozeCriteria(key, i)); showBadge.putBoolean(key, getShowBadge(i)); userSentiment.putInt(key, getUserSentiment(i)); mHidden.putBoolean(key, getHidden(i)); smartActions.putParcelableArrayList(key, getSmartActions(key, i)); smartReplies.putCharSequenceArrayList(key, getSmartReplies(key, i)); lastAudiblyAlerted.putLong(key, lastAudiblyAlerted(i)); noisy.putBoolean(key, getNoisy(i)); canBubble[i] = canBubble(i); } NotificationRankingUpdate update = new NotificationRankingUpdate(mKeys, interceptedKeys.toArray(new String[0]), visibilityOverrides, suppressedVisualEffects, importance, explanation, overrideGroupKeys, channels, overridePeople, snoozeCriteria, showBadge, userSentiment, mHidden, smartActions, smartReplies, lastAudiblyAlerted, noisy, canBubble); final String key = mKeys[i]; Ranking ranking = new Ranking(); ranking.populate( key, i, !isIntercepted(i), getVisibilityOverride(i), getSuppressedVisualEffects(i), getImportance(i), getExplanation(key), getOverrideGroupKey(key), getChannel(key, i), getPeople(key, i), getSnoozeCriteria(key, i), getShowBadge(i), getUserSentiment(i), getHidden(i), lastAudiblyAlerted(i), getNoisy(i), getSmartActions(key, i), getSmartReplies(key, i), canBubble(i) ); rankings[i] = ranking; } NotificationRankingUpdate update = new NotificationRankingUpdate(rankings); return update; } Loading Loading
core/java/android/service/notification/NotificationListenerService.java +192 −388 File changed.Preview size limit exceeded, changes collapsed. Show changes
core/java/android/service/notification/NotificationRankingUpdate.java +18 −154 Original line number Diff line number Diff line Loading @@ -15,7 +15,6 @@ */ package android.service.notification; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; Loading @@ -23,73 +22,18 @@ import android.os.Parcelable; * @hide */ public class NotificationRankingUpdate implements Parcelable { // TODO: Support incremental updates. private final String[] mKeys; private final String[] mInterceptedKeys; private final Bundle mVisibilityOverrides; private final Bundle mSuppressedVisualEffects; private final int[] mImportance; private final Bundle mImportanceExplanation; private final Bundle mOverrideGroupKeys; private final Bundle mChannels; private final Bundle mOverridePeople; private final Bundle mSnoozeCriteria; private final Bundle mShowBadge; private final Bundle mUserSentiment; private final Bundle mHidden; private final Bundle mSmartActions; private final Bundle mSmartReplies; private final Bundle mLastAudiblyAlerted; private final Bundle mNoisy; private final boolean[] mCanBubble; private final NotificationListenerService.RankingMap mRankingMap; public NotificationRankingUpdate(String[] keys, String[] interceptedKeys, Bundle visibilityOverrides, Bundle suppressedVisualEffects, int[] importance, Bundle explanation, Bundle overrideGroupKeys, Bundle channels, Bundle overridePeople, Bundle snoozeCriteria, Bundle showBadge, Bundle userSentiment, Bundle hidden, Bundle smartActions, Bundle smartReplies, Bundle lastAudiblyAlerted, Bundle noisy, boolean[] canBubble) { mKeys = keys; mInterceptedKeys = interceptedKeys; mVisibilityOverrides = visibilityOverrides; mSuppressedVisualEffects = suppressedVisualEffects; mImportance = importance; mImportanceExplanation = explanation; mOverrideGroupKeys = overrideGroupKeys; mChannels = channels; mOverridePeople = overridePeople; mSnoozeCriteria = snoozeCriteria; mShowBadge = showBadge; mUserSentiment = userSentiment; mHidden = hidden; mSmartActions = smartActions; mSmartReplies = smartReplies; mLastAudiblyAlerted = lastAudiblyAlerted; mNoisy = noisy; mCanBubble = canBubble; public NotificationRankingUpdate(NotificationListenerService.Ranking[] rankings) { mRankingMap = new NotificationListenerService.RankingMap(rankings); } public NotificationRankingUpdate(Parcel in) { mKeys = in.readStringArray(); mInterceptedKeys = in.readStringArray(); mVisibilityOverrides = in.readBundle(); mSuppressedVisualEffects = in.readBundle(); mImportance = new int[mKeys.length]; in.readIntArray(mImportance); mImportanceExplanation = in.readBundle(); mOverrideGroupKeys = in.readBundle(); mChannels = in.readBundle(); mOverridePeople = in.readBundle(); mSnoozeCriteria = in.readBundle(); mShowBadge = in.readBundle(); mUserSentiment = in.readBundle(); mHidden = in.readBundle(); mSmartActions = in.readBundle(); mSmartReplies = in.readBundle(); mLastAudiblyAlerted = in.readBundle(); mNoisy = in.readBundle(); mCanBubble = new boolean[mKeys.length]; in.readBooleanArray(mCanBubble); mRankingMap = in.readParcelable(getClass().getClassLoader()); } public NotificationListenerService.RankingMap getRankingMap() { return mRankingMap; } @Override Loading @@ -97,26 +41,18 @@ public class NotificationRankingUpdate implements Parcelable { return 0; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; NotificationRankingUpdate other = (NotificationRankingUpdate) o; return mRankingMap.equals(other.mRankingMap); } @Override public void writeToParcel(Parcel out, int flags) { out.writeStringArray(mKeys); out.writeStringArray(mInterceptedKeys); out.writeBundle(mVisibilityOverrides); out.writeBundle(mSuppressedVisualEffects); out.writeIntArray(mImportance); out.writeBundle(mImportanceExplanation); out.writeBundle(mOverrideGroupKeys); out.writeBundle(mChannels); out.writeBundle(mOverridePeople); out.writeBundle(mSnoozeCriteria); out.writeBundle(mShowBadge); out.writeBundle(mUserSentiment); out.writeBundle(mHidden); out.writeBundle(mSmartActions); out.writeBundle(mSmartReplies); out.writeBundle(mLastAudiblyAlerted); out.writeBundle(mNoisy); out.writeBooleanArray(mCanBubble); out.writeParcelable(mRankingMap, flags); } public static final @android.annotation.NonNull Parcelable.Creator<NotificationRankingUpdate> CREATOR Loading @@ -129,76 +65,4 @@ public class NotificationRankingUpdate implements Parcelable { return new NotificationRankingUpdate[size]; } }; public String[] getOrderedKeys() { return mKeys; } public String[] getInterceptedKeys() { return mInterceptedKeys; } public Bundle getVisibilityOverrides() { return mVisibilityOverrides; } public Bundle getSuppressedVisualEffects() { return mSuppressedVisualEffects; } public int[] getImportance() { return mImportance; } public Bundle getImportanceExplanation() { return mImportanceExplanation; } public Bundle getOverrideGroupKeys() { return mOverrideGroupKeys; } public Bundle getChannels() { return mChannels; } public Bundle getOverridePeople() { return mOverridePeople; } public Bundle getSnoozeCriteria() { return mSnoozeCriteria; } public Bundle getShowBadge() { return mShowBadge; } public Bundle getUserSentiment() { return mUserSentiment; } public Bundle getHidden() { return mHidden; } public Bundle getSmartActions() { return mSmartActions; } public Bundle getSmartReplies() { return mSmartReplies; } public Bundle getLastAudiblyAlerted() { return mLastAudiblyAlerted; } public Bundle getNoisy() { return mNoisy; } public boolean[] getCanBubble() { return mCanBubble; } }
services/core/java/com/android/server/notification/NotificationManagerService.java +30 −60 Original line number Diff line number Diff line Loading @@ -7234,72 +7234,42 @@ public class NotificationManagerService extends SystemService { @GuardedBy("mNotificationLock") private NotificationRankingUpdate makeRankingUpdateLocked(ManagedServiceInfo info) { final int N = mNotificationList.size(); ArrayList<String> keys = new ArrayList<String>(N); ArrayList<String> interceptedKeys = new ArrayList<String>(N); ArrayList<Integer> importance = new ArrayList<>(N); Bundle overrideGroupKeys = new Bundle(); Bundle visibilityOverrides = new Bundle(); Bundle suppressedVisualEffects = new Bundle(); Bundle explanation = new Bundle(); Bundle channels = new Bundle(); Bundle overridePeople = new Bundle(); Bundle snoozeCriteria = new Bundle(); Bundle showBadge = new Bundle(); Bundle userSentiment = new Bundle(); Bundle hidden = new Bundle(); Bundle systemGeneratedSmartActions = new Bundle(); Bundle smartReplies = new Bundle(); Bundle lastAudiblyAlerted = new Bundle(); Bundle noisy = new Bundle(); ArrayList<Boolean> canBubble = new ArrayList<>(N); final ArrayList<NotificationListenerService.Ranking> rankings = new ArrayList<>(); for (int i = 0; i < N; i++) { NotificationRecord record = mNotificationList.get(i); if (!isVisibleToListener(record.sbn, info)) { continue; } final String key = record.sbn.getKey(); keys.add(key); importance.add(record.getImportance()); if (record.getImportanceExplanation() != null) { explanation.putCharSequence(key, record.getImportanceExplanation()); } if (record.isIntercepted()) { interceptedKeys.add(key); } suppressedVisualEffects.putInt(key, record.getSuppressedVisualEffects()); if (record.getPackageVisibilityOverride() != NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE) { visibilityOverrides.putInt(key, record.getPackageVisibilityOverride()); } overrideGroupKeys.putString(key, record.sbn.getOverrideGroupKey()); channels.putParcelable(key, record.getChannel()); overridePeople.putStringArrayList(key, record.getPeopleOverride()); snoozeCriteria.putParcelableArrayList(key, record.getSnoozeCriteria()); showBadge.putBoolean(key, record.canShowBadge()); userSentiment.putInt(key, record.getUserSentiment()); hidden.putBoolean(key, record.isHidden()); systemGeneratedSmartActions.putParcelableArrayList(key, record.getSystemGeneratedSmartActions()); smartReplies.putCharSequenceArrayList(key, record.getSmartReplies()); lastAudiblyAlerted.putLong(key, record.getLastAudiblyAlertedMs()); noisy.putBoolean(key, record.getSound() != null || record.getVibration() != null); canBubble.add(record.canBubble()); } final int M = keys.size(); String[] keysAr = keys.toArray(new String[M]); String[] interceptedKeysAr = interceptedKeys.toArray(new String[interceptedKeys.size()]); int[] importanceAr = new int[M]; boolean[] canBubbleAr = new boolean[M]; for (int i = 0; i < M; i++) { importanceAr[i] = importance.get(i); canBubbleAr[i] = canBubble.get(i); } return new NotificationRankingUpdate(keysAr, interceptedKeysAr, visibilityOverrides, suppressedVisualEffects, importanceAr, explanation, overrideGroupKeys, channels, overridePeople, snoozeCriteria, showBadge, userSentiment, hidden, systemGeneratedSmartActions, smartReplies, lastAudiblyAlerted, noisy, canBubbleAr); final NotificationListenerService.Ranking ranking = new NotificationListenerService.Ranking(); ranking.populate( key, rankings.size(), !record.isIntercepted(), record.getPackageVisibilityOverride(), record.getSuppressedVisualEffects(), record.getImportance(), record.getImportanceExplanation(), record.sbn.getOverrideGroupKey(), record.getChannel(), record.getPeopleOverride(), record.getSnoozeCriteria(), record.canShowBadge(), record.getUserSentiment(), record.isHidden(), record.getLastAudiblyAlertedMs(), record.getSound() != null || record.getVibration() != null, record.getSystemGeneratedSmartActions(), record.getSmartReplies(), record.canBubble() ); rankings.add(ranking); } return new NotificationRankingUpdate( rankings.toArray(new NotificationListenerService.Ranking[0])); } boolean hasCompanionDevice(ManagedServiceInfo info) { Loading
services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java +139 −46 Original line number Diff line number Diff line Loading @@ -20,7 +20,9 @@ import static android.service.notification.NotificationListenerService.Ranking.U import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL; import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_POSITIVE; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; Loading @@ -33,10 +35,11 @@ import android.app.NotificationChannel; import android.app.PendingIntent; import android.content.Intent; import android.os.Binder; import android.os.Bundle; import android.os.IBinder; import android.os.Parcel; import android.service.notification.NotificationListenerService; import android.service.notification.NotificationListenerService.Ranking; import android.service.notification.NotificationListenerService.RankingMap; import android.service.notification.NotificationRankingUpdate; import android.service.notification.SnoozeCriterion; import android.test.suitebuilder.annotation.SmallTest; Loading @@ -55,8 +58,6 @@ import java.util.List; @RunWith(AndroidJUnit4.class) public class NotificationListenerServiceTest extends UiServiceTestCase { private String[] mKeys = new String[] { "key", "key1", "key2", "key3", "key4"}; @Test public void testGetActiveNotifications_notNull() throws Exception { TestListenerService service = new TestListenerService(); Loading Loading @@ -97,52 +98,144 @@ public class NotificationListenerServiceTest extends UiServiceTestCase { } } private NotificationRankingUpdate generateUpdate() { List<String> interceptedKeys = new ArrayList<>(); Bundle visibilityOverrides = new Bundle(); Bundle overrideGroupKeys = new Bundle(); Bundle suppressedVisualEffects = new Bundle(); Bundle explanation = new Bundle(); Bundle channels = new Bundle(); Bundle overridePeople = new Bundle(); Bundle snoozeCriteria = new Bundle(); Bundle showBadge = new Bundle(); int[] importance = new int[mKeys.length]; Bundle userSentiment = new Bundle(); Bundle mHidden = new Bundle(); Bundle smartActions = new Bundle(); Bundle smartReplies = new Bundle(); Bundle lastAudiblyAlerted = new Bundle(); Bundle noisy = new Bundle(); boolean[] canBubble = new boolean[mKeys.length]; // Tests parceling of NotificationRankingUpdate, and by extension, RankingMap and Ranking. @Test public void testRankingUpdate_parcel() { NotificationRankingUpdate nru = generateUpdate(); Parcel parcel = Parcel.obtain(); nru.writeToParcel(parcel, 0); parcel.setDataPosition(0); NotificationRankingUpdate nru1 = NotificationRankingUpdate.CREATOR.createFromParcel(parcel); assertEquals(nru, nru1); } private void detailedAssertEquals(RankingMap a, RankingMap b) { Ranking arank = new Ranking(); Ranking brank = new Ranking(); assertArrayEquals(a.getOrderedKeys(), b.getOrderedKeys()); for (String key : a.getOrderedKeys()) { a.getRanking(key, arank); b.getRanking(key, brank); detailedAssertEquals("ranking for key <" + key + ">", arank, brank); } } // Tests parceling of RankingMap and RankingMap.equals @Test public void testRankingMap_parcel() { RankingMap rmap = generateUpdate().getRankingMap(); Parcel parcel = Parcel.obtain(); rmap.writeToParcel(parcel, 0); parcel.setDataPosition(0); RankingMap rmap1 = RankingMap.CREATOR.createFromParcel(parcel); detailedAssertEquals(rmap, rmap1); assertEquals(rmap, rmap1); } private void detailedAssertEquals(String comment, Ranking a, Ranking b) { assertEquals(comment, a.getKey(), b.getKey()); assertEquals(comment, a.getRank(), b.getRank()); assertEquals(comment, a.matchesInterruptionFilter(), b.matchesInterruptionFilter()); assertEquals(comment, a.getVisibilityOverride(), b.getVisibilityOverride()); assertEquals(comment, a.getSuppressedVisualEffects(), b.getSuppressedVisualEffects()); assertEquals(comment, a.getImportance(), b.getImportance()); assertEquals(comment, a.getImportanceExplanation(), b.getImportanceExplanation()); assertEquals(comment, a.getOverrideGroupKey(), b.getOverrideGroupKey()); assertEquals(comment, a.getChannel(), b.getChannel()); assertEquals(comment, a.getAdditionalPeople(), b.getAdditionalPeople()); assertEquals(comment, a.getSnoozeCriteria(), b.getSnoozeCriteria()); assertEquals(comment, a.canShowBadge(), b.canShowBadge()); assertEquals(comment, a.getUserSentiment(), b.getUserSentiment()); assertEquals(comment, a.isSuspended(), b.isSuspended()); assertEquals(comment, a.getLastAudiblyAlertedMillis(), b.getLastAudiblyAlertedMillis()); assertEquals(comment, a.isNoisy(), b.isNoisy()); assertEquals(comment, a.getSmartReplies(), b.getSmartReplies()); assertEquals(comment, a.canBubble(), b.canBubble()); assertActionsEqual(a.getSmartActions(), b.getSmartActions()); } // Tests parceling of Ranking and Ranking.equals @Test public void testRanking_parcel() { Ranking ranking = generateUpdate().getRankingMap().getRawRankingObject(mKeys[0]); Parcel parcel = Parcel.obtain(); ranking.writeToParcel(parcel, 0); parcel.setDataPosition(0); Ranking ranking1 = new Ranking(parcel); detailedAssertEquals("rankings differ: ", ranking, ranking1); assertEquals(ranking, ranking1); } private void detailedAssertEquals(NotificationRankingUpdate a, NotificationRankingUpdate b) { assertEquals(a.getRankingMap(), b.getRankingMap()); } // Tests NotificationRankingUpdate.equals(), and by extension, RankingMap and Ranking. @Test public void testRankingUpdate_equals() { NotificationRankingUpdate nru = generateUpdate(); NotificationRankingUpdate nru2 = generateUpdate(); detailedAssertEquals(nru, nru2); assertEquals(nru, nru2); Ranking tweak = nru2.getRankingMap().getRawRankingObject(mKeys[0]); tweak.populate( tweak.getKey(), tweak.getRank(), !tweak.matchesInterruptionFilter(), // note the inversion here! tweak.getVisibilityOverride(), tweak.getSuppressedVisualEffects(), tweak.getImportance(), tweak.getImportanceExplanation(), tweak.getOverrideGroupKey(), tweak.getChannel(), (ArrayList) tweak.getAdditionalPeople(), (ArrayList) tweak.getSnoozeCriteria(), tweak.canShowBadge(), tweak.getUserSentiment(), tweak.isSuspended(), tweak.getLastAudiblyAlertedMillis(), tweak.isNoisy(), (ArrayList) tweak.getSmartActions(), (ArrayList) tweak.getSmartReplies(), tweak.canBubble() ); assertNotEquals(nru, nru2); } // Test data private String[] mKeys = new String[] { "key", "key1", "key2", "key3", "key4"}; private NotificationRankingUpdate generateUpdate() { Ranking[] rankings = new Ranking[mKeys.length]; for (int i = 0; i < mKeys.length; i++) { String key = mKeys[i]; visibilityOverrides.putInt(key, getVisibilityOverride(i)); overrideGroupKeys.putString(key, getOverrideGroupKey(key)); if (isIntercepted(i)) { interceptedKeys.add(key); } suppressedVisualEffects.putInt(key, getSuppressedVisualEffects(i)); importance[i] = getImportance(i); explanation.putString(key, getExplanation(key)); channels.putParcelable(key, getChannel(key, i)); overridePeople.putStringArrayList(key, getPeople(key, i)); snoozeCriteria.putParcelableArrayList(key, getSnoozeCriteria(key, i)); showBadge.putBoolean(key, getShowBadge(i)); userSentiment.putInt(key, getUserSentiment(i)); mHidden.putBoolean(key, getHidden(i)); smartActions.putParcelableArrayList(key, getSmartActions(key, i)); smartReplies.putCharSequenceArrayList(key, getSmartReplies(key, i)); lastAudiblyAlerted.putLong(key, lastAudiblyAlerted(i)); noisy.putBoolean(key, getNoisy(i)); canBubble[i] = canBubble(i); } NotificationRankingUpdate update = new NotificationRankingUpdate(mKeys, interceptedKeys.toArray(new String[0]), visibilityOverrides, suppressedVisualEffects, importance, explanation, overrideGroupKeys, channels, overridePeople, snoozeCriteria, showBadge, userSentiment, mHidden, smartActions, smartReplies, lastAudiblyAlerted, noisy, canBubble); final String key = mKeys[i]; Ranking ranking = new Ranking(); ranking.populate( key, i, !isIntercepted(i), getVisibilityOverride(i), getSuppressedVisualEffects(i), getImportance(i), getExplanation(key), getOverrideGroupKey(key), getChannel(key, i), getPeople(key, i), getSnoozeCriteria(key, i), getShowBadge(i), getUserSentiment(i), getHidden(i), lastAudiblyAlerted(i), getNoisy(i), getSmartActions(key, i), getSmartReplies(key, i), canBubble(i) ); rankings[i] = ranking; } NotificationRankingUpdate update = new NotificationRankingUpdate(rankings); return update; } Loading