diff options
author | Danning Chen <danningc@google.com> | 2020-04-21 10:28:52 -0700 |
---|---|---|
committer | Danning Chen <danningc@google.com> | 2020-04-23 13:52:44 -0700 |
commit | 28410f3def3cfea46932e7a313ce71d2010d12c1 (patch) | |
tree | 69100b281f86ac2c124c35459bb8e22ed9479fd8 /services/people | |
parent | 8386c222c9cc1178447bcacb4a3e852a136fd35c (diff) |
Cache the shortcut when the associated notifications are posted and uncache when they are gone
Change-Id: Ia569f9b31a0fe73242f2e6350805afe7c06d2cdf
Bug: 153357090
Test: Manual test
Test: atest DataManagerTest
Test: atest NotificationManagerServiceTest
Diffstat (limited to 'services/people')
-rw-r--r-- | services/people/java/com/android/server/people/data/ConversationInfo.java | 12 | ||||
-rw-r--r-- | services/people/java/com/android/server/people/data/DataManager.java | 78 |
2 files changed, 69 insertions, 21 deletions
diff --git a/services/people/java/com/android/server/people/data/ConversationInfo.java b/services/people/java/com/android/server/people/data/ConversationInfo.java index dc3fa2a048f6..27fa36b70b8f 100644 --- a/services/people/java/com/android/server/people/data/ConversationInfo.java +++ b/services/people/java/com/android/server/people/data/ConversationInfo.java @@ -62,6 +62,8 @@ public class ConversationInfo { private static final int FLAG_DEMOTED = 1 << 6; + private static final int FLAG_NOTIFICATION_SETTING_CHANGED = 1 << 7; + @IntDef(flag = true, prefix = {"FLAG_"}, value = { FLAG_IMPORTANT, FLAG_NOTIFICATION_SILENCED, @@ -70,6 +72,7 @@ public class ConversationInfo { FLAG_PERSON_BOT, FLAG_CONTACT_STARRED, FLAG_DEMOTED, + FLAG_NOTIFICATION_SETTING_CHANGED, }) @Retention(RetentionPolicy.SOURCE) private @interface ConversationFlags { @@ -185,6 +188,11 @@ public class ConversationInfo { return hasConversationFlags(FLAG_CONTACT_STARRED); } + /** Whether the conversation's notification setting has ever been changed by the user. */ + boolean isNotificationSettingChanged() { + return hasConversationFlags(FLAG_NOTIFICATION_SETTING_CHANGED); + } + @Override public boolean equals(Object obj) { if (this == obj) { @@ -491,6 +499,10 @@ public class ConversationInfo { return setConversationFlag(FLAG_CONTACT_STARRED, value); } + Builder setNotificationSettingChanged(boolean value) { + return setConversationFlag(FLAG_NOTIFICATION_SETTING_CHANGED, value); + } + private Builder setConversationFlag(@ConversationFlags int flags, boolean value) { if (value) { return addConversationFlags(flags); diff --git a/services/people/java/com/android/server/people/data/DataManager.java b/services/people/java/com/android/server/people/data/DataManager.java index 763e19bd14ab..8e1141da9df1 100644 --- a/services/people/java/com/android/server/people/data/DataManager.java +++ b/services/people/java/com/android/server/people/data/DataManager.java @@ -16,6 +16,8 @@ package com.android.server.people.data; +import static android.app.NotificationChannel.USER_LOCKED_ALLOW_BUBBLE; + import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; @@ -56,6 +58,7 @@ import android.service.notification.NotificationListenerService; import android.service.notification.StatusBarNotification; import android.telecom.TelecomManager; import android.text.format.DateUtils; +import android.util.ArrayMap; import android.util.ArraySet; import android.util.Slog; import android.util.SparseArray; @@ -482,7 +485,8 @@ public class DataManager { } @Nullable - private EventHistoryImpl getEventHistoryIfEligible(StatusBarNotification sbn) { + private PackageData getPackageIfConversationExists(StatusBarNotification sbn, + Consumer<ConversationInfo> conversationConsumer) { Notification notification = sbn.getNotification(); String shortcutId = notification.getShortcutId(); if (shortcutId == null) { @@ -490,12 +494,16 @@ public class DataManager { } PackageData packageData = getPackage(sbn.getPackageName(), sbn.getUser().getIdentifier()); - if (packageData == null - || packageData.getConversationStore().getConversation(shortcutId) == null) { + if (packageData == null) { + return null; + } + ConversationInfo conversationInfo = + packageData.getConversationStore().getConversation(shortcutId); + if (conversationInfo == null) { return null; } - return packageData.getEventStore().getOrCreateEventHistory( - EventStore.CATEGORY_SHORTCUT_BASED, shortcutId); + conversationConsumer.accept(conversationInfo); + return packageData; } @VisibleForTesting @@ -745,10 +753,19 @@ public class DataManager { /** Listener for the notifications and their settings changes. */ private class NotificationListener extends NotificationListenerService { + // Conversation shortcut ID -> Number of active notifications + private final Map<String, Integer> mActiveNotifCounts = new ArrayMap<>(); + @Override public void onNotificationPosted(StatusBarNotification sbn) { - EventHistoryImpl eventHistory = getEventHistoryIfEligible(sbn); - if (eventHistory != null) { + String shortcutId = sbn.getNotification().getShortcutId(); + PackageData packageData = getPackageIfConversationExists(sbn, conversationInfo -> { + mActiveNotifCounts.merge(shortcutId, 1, Integer::sum); + }); + + if (packageData != null) { + EventHistoryImpl eventHistory = packageData.getEventStore().getOrCreateEventHistory( + EventStore.CATEGORY_SHORTCUT_BASED, shortcutId); eventHistory.addEvent(new Event(sbn.getPostTime(), Event.TYPE_NOTIFICATION_POSTED)); } } @@ -756,13 +773,32 @@ public class DataManager { @Override public void onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap, int reason) { - if (reason != REASON_CLICK) { - return; - } - EventHistoryImpl eventHistory = getEventHistoryIfEligible(sbn); - if (eventHistory == null) { + String shortcutId = sbn.getNotification().getShortcutId(); + PackageData packageData = getPackageIfConversationExists(sbn, conversationInfo -> { + int count = mActiveNotifCounts.getOrDefault(shortcutId, 0) - 1; + if (count <= 0) { + mActiveNotifCounts.remove(sbn.getNotification().getShortcutId()); + // The shortcut was cached by Notification Manager synchronously when the + // associated notification was posted. Uncache it here when all the associated + // notifications are removed. + if (conversationInfo.isShortcutCached() + && !conversationInfo.isNotificationSettingChanged()) { + int userId = sbn.getUser().getIdentifier(); + mShortcutServiceInternal.uncacheShortcuts(userId, + mContext.getPackageName(), sbn.getPackageName(), + Collections.singletonList(conversationInfo.getShortcutId()), + userId); + } + } else { + mActiveNotifCounts.put(shortcutId, count); + } + }); + + if (reason != REASON_CLICK || packageData == null) { return; } + EventHistoryImpl eventHistory = packageData.getEventStore().getOrCreateEventHistory( + EventStore.CATEGORY_SHORTCUT_BASED, shortcutId); long currentTime = System.currentTimeMillis(); eventHistory.addEvent(new Event(currentTime, Event.TYPE_NOTIFICATION_OPENED)); } @@ -780,7 +816,16 @@ public class DataManager { if (conversationInfo == null) { return; } + boolean isNotificationSettingChanged = + conversationInfo.isImportant() != channel.isImportantConversation() + || conversationInfo.isDemoted() != channel.isDemoted() + || channel.hasUserSetImportance() + || (channel.getUserLockedFields() & USER_LOCKED_ALLOW_BUBBLE) != 0; ConversationInfo.Builder builder = new ConversationInfo.Builder(conversationInfo); + if (modificationType == NOTIFICATION_CHANNEL_OR_GROUP_UPDATED + && isNotificationSettingChanged) { + builder.setNotificationSettingChanged(true); + } switch (modificationType) { case NOTIFICATION_CHANNEL_OR_GROUP_ADDED: case NOTIFICATION_CHANNEL_OR_GROUP_UPDATED: @@ -802,15 +847,6 @@ public class DataManager { break; } conversationStore.addOrUpdate(builder.build()); - - if (modificationType == NOTIFICATION_CHANNEL_OR_GROUP_UPDATED - && conversationInfo.isShortcutLongLived() - && !conversationInfo.isShortcutCached()) { - mShortcutServiceInternal.cacheShortcuts(user.getIdentifier(), - mContext.getPackageName(), pkg, - Collections.singletonList(conversationInfo.getShortcutId()), - user.getIdentifier()); - } } } |