summaryrefslogtreecommitdiff
path: root/services/people
diff options
context:
space:
mode:
authorDanning Chen <danningc@google.com>2020-04-21 10:28:52 -0700
committerDanning Chen <danningc@google.com>2020-04-23 13:52:44 -0700
commit28410f3def3cfea46932e7a313ce71d2010d12c1 (patch)
tree69100b281f86ac2c124c35459bb8e22ed9479fd8 /services/people
parent8386c222c9cc1178447bcacb4a3e852a136fd35c (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.java12
-rw-r--r--services/people/java/com/android/server/people/data/DataManager.java78
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());
- }
}
}