summaryrefslogtreecommitdiff
path: root/services/people
diff options
context:
space:
mode:
authorDanning Chen <danningc@google.com>2020-04-27 18:07:02 -0700
committerDanning Chen <danningc@google.com>2020-04-30 23:37:56 -0700
commitf4ba1c22a6c95e5250bd065c76106190d77d9a93 (patch)
tree6a3b96e85ed2611b29d37c753c405d85b549e0ea /services/people
parent761c9334805a6bd6973446f5dc099a85c0769267 (diff)
Uncache the shortcuts when Android system shuts down if the notification settings are not changed
Change-Id: Ib7e23f4b15ccca9c162cea187a26e7d89b8976a8 Test: Manual test Test: atest DataManagerTest Bug: 153357090
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.java128
2 files changed, 93 insertions, 47 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 27fa36b70b8f..dc3fa2a048f6 100644
--- a/services/people/java/com/android/server/people/data/ConversationInfo.java
+++ b/services/people/java/com/android/server/people/data/ConversationInfo.java
@@ -62,8 +62,6 @@ 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,
@@ -72,7 +70,6 @@ public class ConversationInfo {
FLAG_PERSON_BOT,
FLAG_CONTACT_STARRED,
FLAG_DEMOTED,
- FLAG_NOTIFICATION_SETTING_CHANGED,
})
@Retention(RetentionPolicy.SOURCE)
private @interface ConversationFlags {
@@ -188,11 +185,6 @@ 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) {
@@ -499,10 +491,6 @@ 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 8e1141da9df1..d9ca4152026e 100644
--- a/services/people/java/com/android/server/people/data/DataManager.java
+++ b/services/people/java/com/android/server/people/data/DataManager.java
@@ -16,8 +16,6 @@
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;
@@ -60,9 +58,11 @@ import android.telecom.TelecomManager;
import android.text.format.DateUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
+import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.ChooserActivity;
import com.android.internal.content.PackageMonitor;
@@ -106,8 +106,7 @@ public class DataManager {
private final SparseArray<BroadcastReceiver> mBroadcastReceivers = new SparseArray<>();
private final SparseArray<ContentObserver> mContactsContentObservers = new SparseArray<>();
private final SparseArray<ScheduledFuture<?>> mUsageStatsQueryFutures = new SparseArray<>();
- private final SparseArray<NotificationListenerService> mNotificationListeners =
- new SparseArray<>();
+ private final SparseArray<NotificationListener> mNotificationListeners = new SparseArray<>();
private final SparseArray<PackageMonitor> mPackageMonitors = new SparseArray<>();
private ContentObserver mCallLogContentObserver;
private ContentObserver mMmsSmsContentObserver;
@@ -272,6 +271,7 @@ public class DataManager {
}
pruneUninstalledPackageData(userData);
+ final NotificationListener notificationListener = mNotificationListeners.get(userId);
userData.forAllPackages(packageData -> {
if (signal.isCanceled()) {
return;
@@ -284,6 +284,20 @@ public class DataManager {
packageData.getEventStore().deleteEventHistories(EventStore.CATEGORY_SMS);
}
packageData.pruneOrphanEvents();
+ if (notificationListener != null) {
+ String packageName = packageData.getPackageName();
+ packageData.forAllConversations(conversationInfo -> {
+ if (conversationInfo.isShortcutCached()
+ && conversationInfo.getNotificationChannelId() == null
+ && !notificationListener.hasActiveNotifications(
+ packageName, conversationInfo.getShortcutId())) {
+ mShortcutServiceInternal.uncacheShortcuts(userId,
+ mContext.getPackageName(), packageName,
+ Collections.singletonList(conversationInfo.getShortcutId()),
+ userId);
+ }
+ });
+ }
});
}
@@ -337,7 +351,7 @@ public class DataManager {
Contacts.CONTENT_URI, /* notifyForDescendants= */ true,
contactsContentObserver, userId);
- NotificationListener notificationListener = new NotificationListener();
+ NotificationListener notificationListener = new NotificationListener(userId);
mNotificationListeners.put(userId, notificationListener);
try {
notificationListener.registerAsSystemService(mContext,
@@ -753,14 +767,27 @@ 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<>();
+ private final int mUserId;
+
+ // Conversation package name + shortcut ID -> Number of active notifications
+ @GuardedBy("this")
+ private final Map<Pair<String, String>, Integer> mActiveNotifCounts = new ArrayMap<>();
+
+ private NotificationListener(int userId) {
+ mUserId = userId;
+ }
@Override
public void onNotificationPosted(StatusBarNotification sbn) {
+ if (sbn.getUser().getIdentifier() != mUserId) {
+ return;
+ }
String shortcutId = sbn.getNotification().getShortcutId();
PackageData packageData = getPackageIfConversationExists(sbn, conversationInfo -> {
- mActiveNotifCounts.merge(shortcutId, 1, Integer::sum);
+ synchronized (this) {
+ mActiveNotifCounts.merge(
+ Pair.create(sbn.getPackageName(), shortcutId), 1, Integer::sum);
+ }
});
if (packageData != null) {
@@ -771,26 +798,32 @@ public class DataManager {
}
@Override
- public void onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap,
- int reason) {
+ public synchronized void onNotificationRemoved(StatusBarNotification sbn,
+ RankingMap rankingMap, int reason) {
+ if (sbn.getUser().getIdentifier() != mUserId) {
+ return;
+ }
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);
+ Pair<String, String> conversationKey =
+ Pair.create(sbn.getPackageName(), shortcutId);
+ synchronized (this) {
+ int count = mActiveNotifCounts.getOrDefault(conversationKey, 0) - 1;
+ if (count <= 0) {
+ mActiveNotifCounts.remove(conversationKey);
+ // 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.getNotificationChannelId() == null) {
+ mShortcutServiceInternal.uncacheShortcuts(mUserId,
+ mContext.getPackageName(), sbn.getPackageName(),
+ Collections.singletonList(conversationInfo.getShortcutId()),
+ mUserId);
+ }
+ } else {
+ mActiveNotifCounts.put(conversationKey, count);
}
- } else {
- mActiveNotifCounts.put(shortcutId, count);
}
});
@@ -806,6 +839,9 @@ public class DataManager {
@Override
public void onNotificationChannelModified(String pkg, UserHandle user,
NotificationChannel channel, int modificationType) {
+ if (user.getIdentifier() != mUserId) {
+ return;
+ }
PackageData packageData = getPackage(pkg, user.getIdentifier());
String shortcutId = channel.getConversationId();
if (packageData == null || shortcutId == null) {
@@ -816,16 +852,7 @@ 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:
@@ -848,6 +875,28 @@ public class DataManager {
}
conversationStore.addOrUpdate(builder.build());
}
+
+ synchronized void cleanupCachedShortcuts() {
+ for (Pair<String, String> conversationKey : mActiveNotifCounts.keySet()) {
+ String packageName = conversationKey.first;
+ String shortcutId = conversationKey.second;
+ PackageData packageData = getPackage(packageName, mUserId);
+ ConversationInfo conversationInfo =
+ packageData != null ? packageData.getConversationInfo(shortcutId) : null;
+ if (conversationInfo != null
+ && conversationInfo.isShortcutCached()
+ && conversationInfo.getNotificationChannelId() == null) {
+ mShortcutServiceInternal.uncacheShortcuts(mUserId,
+ mContext.getPackageName(), packageName,
+ Collections.singletonList(shortcutId),
+ mUserId);
+ }
+ }
+ }
+
+ synchronized boolean hasActiveNotifications(String packageName, String shortcutId) {
+ return mActiveNotifCounts.containsKey(Pair.create(packageName, shortcutId));
+ }
}
/**
@@ -917,7 +966,16 @@ public class DataManager {
@Override
public void onReceive(Context context, Intent intent) {
- forAllUnlockedUsers(userData -> userData.forAllPackages(PackageData::saveToDisk));
+ forAllUnlockedUsers(userData -> {
+ NotificationListener listener = mNotificationListeners.get(userData.getUserId());
+ // Clean up the cached shortcuts because all the notifications are cleared after
+ // system shutdown. The associated shortcuts need to be uncached to keep in sync
+ // unless the settings are changed by the user.
+ if (listener != null) {
+ listener.cleanupCachedShortcuts();
+ }
+ userData.forAllPackages(PackageData::saveToDisk);
+ });
}
}