Merge "Uncache the shortcuts when Android system shuts down if the notification settings are not changed" into rvc-dev
This commit is contained in:
@@ -62,8 +62,6 @@ public class ConversationInfo {
|
|||||||
|
|
||||||
private static final int FLAG_DEMOTED = 1 << 6;
|
private static final int FLAG_DEMOTED = 1 << 6;
|
||||||
|
|
||||||
private static final int FLAG_NOTIFICATION_SETTING_CHANGED = 1 << 7;
|
|
||||||
|
|
||||||
@IntDef(flag = true, prefix = {"FLAG_"}, value = {
|
@IntDef(flag = true, prefix = {"FLAG_"}, value = {
|
||||||
FLAG_IMPORTANT,
|
FLAG_IMPORTANT,
|
||||||
FLAG_NOTIFICATION_SILENCED,
|
FLAG_NOTIFICATION_SILENCED,
|
||||||
@@ -72,7 +70,6 @@ public class ConversationInfo {
|
|||||||
FLAG_PERSON_BOT,
|
FLAG_PERSON_BOT,
|
||||||
FLAG_CONTACT_STARRED,
|
FLAG_CONTACT_STARRED,
|
||||||
FLAG_DEMOTED,
|
FLAG_DEMOTED,
|
||||||
FLAG_NOTIFICATION_SETTING_CHANGED,
|
|
||||||
})
|
})
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
private @interface ConversationFlags {
|
private @interface ConversationFlags {
|
||||||
@@ -188,11 +185,6 @@ public class ConversationInfo {
|
|||||||
return hasConversationFlags(FLAG_CONTACT_STARRED);
|
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
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (this == obj) {
|
if (this == obj) {
|
||||||
@@ -499,10 +491,6 @@ public class ConversationInfo {
|
|||||||
return setConversationFlag(FLAG_CONTACT_STARRED, value);
|
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) {
|
private Builder setConversationFlag(@ConversationFlags int flags, boolean value) {
|
||||||
if (value) {
|
if (value) {
|
||||||
return addConversationFlags(flags);
|
return addConversationFlags(flags);
|
||||||
|
|||||||
@@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
package com.android.server.people.data;
|
package com.android.server.people.data;
|
||||||
|
|
||||||
import static android.app.NotificationChannel.USER_LOCKED_ALLOW_BUBBLE;
|
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.annotation.UserIdInt;
|
import android.annotation.UserIdInt;
|
||||||
@@ -60,9 +58,11 @@ import android.telecom.TelecomManager;
|
|||||||
import android.text.format.DateUtils;
|
import android.text.format.DateUtils;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
import android.util.ArraySet;
|
import android.util.ArraySet;
|
||||||
|
import android.util.Pair;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
|
|
||||||
|
import com.android.internal.annotations.GuardedBy;
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.internal.app.ChooserActivity;
|
import com.android.internal.app.ChooserActivity;
|
||||||
import com.android.internal.content.PackageMonitor;
|
import com.android.internal.content.PackageMonitor;
|
||||||
@@ -106,8 +106,7 @@ public class DataManager {
|
|||||||
private final SparseArray<BroadcastReceiver> mBroadcastReceivers = new SparseArray<>();
|
private final SparseArray<BroadcastReceiver> mBroadcastReceivers = new SparseArray<>();
|
||||||
private final SparseArray<ContentObserver> mContactsContentObservers = new SparseArray<>();
|
private final SparseArray<ContentObserver> mContactsContentObservers = new SparseArray<>();
|
||||||
private final SparseArray<ScheduledFuture<?>> mUsageStatsQueryFutures = new SparseArray<>();
|
private final SparseArray<ScheduledFuture<?>> mUsageStatsQueryFutures = new SparseArray<>();
|
||||||
private final SparseArray<NotificationListenerService> mNotificationListeners =
|
private final SparseArray<NotificationListener> mNotificationListeners = new SparseArray<>();
|
||||||
new SparseArray<>();
|
|
||||||
private final SparseArray<PackageMonitor> mPackageMonitors = new SparseArray<>();
|
private final SparseArray<PackageMonitor> mPackageMonitors = new SparseArray<>();
|
||||||
private ContentObserver mCallLogContentObserver;
|
private ContentObserver mCallLogContentObserver;
|
||||||
private ContentObserver mMmsSmsContentObserver;
|
private ContentObserver mMmsSmsContentObserver;
|
||||||
@@ -272,6 +271,7 @@ public class DataManager {
|
|||||||
}
|
}
|
||||||
pruneUninstalledPackageData(userData);
|
pruneUninstalledPackageData(userData);
|
||||||
|
|
||||||
|
final NotificationListener notificationListener = mNotificationListeners.get(userId);
|
||||||
userData.forAllPackages(packageData -> {
|
userData.forAllPackages(packageData -> {
|
||||||
if (signal.isCanceled()) {
|
if (signal.isCanceled()) {
|
||||||
return;
|
return;
|
||||||
@@ -284,6 +284,20 @@ public class DataManager {
|
|||||||
packageData.getEventStore().deleteEventHistories(EventStore.CATEGORY_SMS);
|
packageData.getEventStore().deleteEventHistories(EventStore.CATEGORY_SMS);
|
||||||
}
|
}
|
||||||
packageData.pruneOrphanEvents();
|
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,
|
Contacts.CONTENT_URI, /* notifyForDescendants= */ true,
|
||||||
contactsContentObserver, userId);
|
contactsContentObserver, userId);
|
||||||
|
|
||||||
NotificationListener notificationListener = new NotificationListener();
|
NotificationListener notificationListener = new NotificationListener(userId);
|
||||||
mNotificationListeners.put(userId, notificationListener);
|
mNotificationListeners.put(userId, notificationListener);
|
||||||
try {
|
try {
|
||||||
notificationListener.registerAsSystemService(mContext,
|
notificationListener.registerAsSystemService(mContext,
|
||||||
@@ -753,14 +767,27 @@ public class DataManager {
|
|||||||
/** Listener for the notifications and their settings changes. */
|
/** Listener for the notifications and their settings changes. */
|
||||||
private class NotificationListener extends NotificationListenerService {
|
private class NotificationListener extends NotificationListenerService {
|
||||||
|
|
||||||
// Conversation shortcut ID -> Number of active notifications
|
private final int mUserId;
|
||||||
private final Map<String, Integer> mActiveNotifCounts = new ArrayMap<>();
|
|
||||||
|
// 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
|
@Override
|
||||||
public void onNotificationPosted(StatusBarNotification sbn) {
|
public void onNotificationPosted(StatusBarNotification sbn) {
|
||||||
|
if (sbn.getUser().getIdentifier() != mUserId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
String shortcutId = sbn.getNotification().getShortcutId();
|
String shortcutId = sbn.getNotification().getShortcutId();
|
||||||
PackageData packageData = getPackageIfConversationExists(sbn, conversationInfo -> {
|
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) {
|
if (packageData != null) {
|
||||||
@@ -771,26 +798,32 @@ public class DataManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap,
|
public synchronized void onNotificationRemoved(StatusBarNotification sbn,
|
||||||
int reason) {
|
RankingMap rankingMap, int reason) {
|
||||||
|
if (sbn.getUser().getIdentifier() != mUserId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
String shortcutId = sbn.getNotification().getShortcutId();
|
String shortcutId = sbn.getNotification().getShortcutId();
|
||||||
PackageData packageData = getPackageIfConversationExists(sbn, conversationInfo -> {
|
PackageData packageData = getPackageIfConversationExists(sbn, conversationInfo -> {
|
||||||
int count = mActiveNotifCounts.getOrDefault(shortcutId, 0) - 1;
|
Pair<String, String> conversationKey =
|
||||||
|
Pair.create(sbn.getPackageName(), shortcutId);
|
||||||
|
synchronized (this) {
|
||||||
|
int count = mActiveNotifCounts.getOrDefault(conversationKey, 0) - 1;
|
||||||
if (count <= 0) {
|
if (count <= 0) {
|
||||||
mActiveNotifCounts.remove(sbn.getNotification().getShortcutId());
|
mActiveNotifCounts.remove(conversationKey);
|
||||||
// The shortcut was cached by Notification Manager synchronously when the
|
// The shortcut was cached by Notification Manager synchronously when the
|
||||||
// associated notification was posted. Uncache it here when all the associated
|
// associated notification was posted. Uncache it here when all the
|
||||||
// notifications are removed.
|
// associated notifications are removed.
|
||||||
if (conversationInfo.isShortcutCached()
|
if (conversationInfo.isShortcutCached()
|
||||||
&& !conversationInfo.isNotificationSettingChanged()) {
|
&& conversationInfo.getNotificationChannelId() == null) {
|
||||||
int userId = sbn.getUser().getIdentifier();
|
mShortcutServiceInternal.uncacheShortcuts(mUserId,
|
||||||
mShortcutServiceInternal.uncacheShortcuts(userId,
|
|
||||||
mContext.getPackageName(), sbn.getPackageName(),
|
mContext.getPackageName(), sbn.getPackageName(),
|
||||||
Collections.singletonList(conversationInfo.getShortcutId()),
|
Collections.singletonList(conversationInfo.getShortcutId()),
|
||||||
userId);
|
mUserId);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
mActiveNotifCounts.put(shortcutId, count);
|
mActiveNotifCounts.put(conversationKey, count);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -806,6 +839,9 @@ public class DataManager {
|
|||||||
@Override
|
@Override
|
||||||
public void onNotificationChannelModified(String pkg, UserHandle user,
|
public void onNotificationChannelModified(String pkg, UserHandle user,
|
||||||
NotificationChannel channel, int modificationType) {
|
NotificationChannel channel, int modificationType) {
|
||||||
|
if (user.getIdentifier() != mUserId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
PackageData packageData = getPackage(pkg, user.getIdentifier());
|
PackageData packageData = getPackage(pkg, user.getIdentifier());
|
||||||
String shortcutId = channel.getConversationId();
|
String shortcutId = channel.getConversationId();
|
||||||
if (packageData == null || shortcutId == null) {
|
if (packageData == null || shortcutId == null) {
|
||||||
@@ -816,16 +852,7 @@ public class DataManager {
|
|||||||
if (conversationInfo == null) {
|
if (conversationInfo == null) {
|
||||||
return;
|
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);
|
ConversationInfo.Builder builder = new ConversationInfo.Builder(conversationInfo);
|
||||||
if (modificationType == NOTIFICATION_CHANNEL_OR_GROUP_UPDATED
|
|
||||||
&& isNotificationSettingChanged) {
|
|
||||||
builder.setNotificationSettingChanged(true);
|
|
||||||
}
|
|
||||||
switch (modificationType) {
|
switch (modificationType) {
|
||||||
case NOTIFICATION_CHANNEL_OR_GROUP_ADDED:
|
case NOTIFICATION_CHANNEL_OR_GROUP_ADDED:
|
||||||
case NOTIFICATION_CHANNEL_OR_GROUP_UPDATED:
|
case NOTIFICATION_CHANNEL_OR_GROUP_UPDATED:
|
||||||
@@ -848,6 +875,28 @@ public class DataManager {
|
|||||||
}
|
}
|
||||||
conversationStore.addOrUpdate(builder.build());
|
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
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
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);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,6 @@ public final class ConversationInfoTest {
|
|||||||
.setPersonImportant(true)
|
.setPersonImportant(true)
|
||||||
.setPersonBot(true)
|
.setPersonBot(true)
|
||||||
.setContactStarred(true)
|
.setContactStarred(true)
|
||||||
.setNotificationSettingChanged(true)
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
assertEquals(SHORTCUT_ID, conversationInfo.getShortcutId());
|
assertEquals(SHORTCUT_ID, conversationInfo.getShortcutId());
|
||||||
@@ -71,7 +70,6 @@ public final class ConversationInfoTest {
|
|||||||
assertTrue(conversationInfo.isPersonImportant());
|
assertTrue(conversationInfo.isPersonImportant());
|
||||||
assertTrue(conversationInfo.isPersonBot());
|
assertTrue(conversationInfo.isPersonBot());
|
||||||
assertTrue(conversationInfo.isContactStarred());
|
assertTrue(conversationInfo.isContactStarred());
|
||||||
assertTrue(conversationInfo.isNotificationSettingChanged());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -94,7 +92,6 @@ public final class ConversationInfoTest {
|
|||||||
assertFalse(conversationInfo.isPersonImportant());
|
assertFalse(conversationInfo.isPersonImportant());
|
||||||
assertFalse(conversationInfo.isPersonBot());
|
assertFalse(conversationInfo.isPersonBot());
|
||||||
assertFalse(conversationInfo.isContactStarred());
|
assertFalse(conversationInfo.isContactStarred());
|
||||||
assertFalse(conversationInfo.isNotificationSettingChanged());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -112,7 +109,6 @@ public final class ConversationInfoTest {
|
|||||||
.setPersonImportant(true)
|
.setPersonImportant(true)
|
||||||
.setPersonBot(true)
|
.setPersonBot(true)
|
||||||
.setContactStarred(true)
|
.setContactStarred(true)
|
||||||
.setNotificationSettingChanged(true)
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
ConversationInfo destination = new ConversationInfo.Builder(source)
|
ConversationInfo destination = new ConversationInfo.Builder(source)
|
||||||
@@ -132,6 +128,5 @@ public final class ConversationInfoTest {
|
|||||||
assertTrue(destination.isPersonImportant());
|
assertTrue(destination.isPersonImportant());
|
||||||
assertTrue(destination.isPersonBot());
|
assertTrue(destination.isPersonBot());
|
||||||
assertFalse(destination.isContactStarred());
|
assertFalse(destination.isContactStarred());
|
||||||
assertTrue(destination.isNotificationSettingChanged());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ import android.app.prediction.AppTarget;
|
|||||||
import android.app.prediction.AppTargetEvent;
|
import android.app.prediction.AppTargetEvent;
|
||||||
import android.app.prediction.AppTargetId;
|
import android.app.prediction.AppTargetId;
|
||||||
import android.app.usage.UsageStatsManagerInternal;
|
import android.app.usage.UsageStatsManagerInternal;
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@@ -95,8 +96,6 @@ import java.util.List;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
@@ -125,18 +124,19 @@ public final class DataManagerTest {
|
|||||||
@Mock private TelephonyManager mTelephonyManager;
|
@Mock private TelephonyManager mTelephonyManager;
|
||||||
@Mock private TelecomManager mTelecomManager;
|
@Mock private TelecomManager mTelecomManager;
|
||||||
@Mock private ContentResolver mContentResolver;
|
@Mock private ContentResolver mContentResolver;
|
||||||
@Mock private ScheduledExecutorService mExecutorService;
|
|
||||||
@Mock private JobScheduler mJobScheduler;
|
@Mock private JobScheduler mJobScheduler;
|
||||||
@Mock private ScheduledFuture mScheduledFuture;
|
|
||||||
@Mock private StatusBarNotification mStatusBarNotification;
|
@Mock private StatusBarNotification mStatusBarNotification;
|
||||||
@Mock private Notification mNotification;
|
@Mock private Notification mNotification;
|
||||||
|
|
||||||
@Captor private ArgumentCaptor<ShortcutChangeCallback> mShortcutChangeCallbackCaptor;
|
@Captor private ArgumentCaptor<ShortcutChangeCallback> mShortcutChangeCallbackCaptor;
|
||||||
|
@Captor private ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor;
|
||||||
|
|
||||||
|
private ScheduledExecutorService mExecutorService;
|
||||||
private NotificationChannel mNotificationChannel;
|
private NotificationChannel mNotificationChannel;
|
||||||
private DataManager mDataManager;
|
private DataManager mDataManager;
|
||||||
private CancellationSignal mCancellationSignal;
|
private CancellationSignal mCancellationSignal;
|
||||||
private ShortcutChangeCallback mShortcutChangeCallback;
|
private ShortcutChangeCallback mShortcutChangeCallback;
|
||||||
|
private BroadcastReceiver mShutdownBroadcastReceiver;
|
||||||
private TestInjector mInjector;
|
private TestInjector mInjector;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
@@ -182,13 +182,7 @@ public final class DataManagerTest {
|
|||||||
when(mContext.getSystemServiceName(JobScheduler.class)).thenReturn(
|
when(mContext.getSystemServiceName(JobScheduler.class)).thenReturn(
|
||||||
Context.JOB_SCHEDULER_SERVICE);
|
Context.JOB_SCHEDULER_SERVICE);
|
||||||
|
|
||||||
when(mExecutorService.scheduleAtFixedRate(any(Runnable.class), anyLong(), anyLong(), any(
|
mExecutorService = new MockScheduledExecutorService();
|
||||||
TimeUnit.class))).thenReturn(mScheduledFuture);
|
|
||||||
doAnswer(ans -> {
|
|
||||||
Runnable runnable = (Runnable) ans.getArguments()[0];
|
|
||||||
runnable.run();
|
|
||||||
return null;
|
|
||||||
}).when(mExecutorService).execute(any(Runnable.class));
|
|
||||||
|
|
||||||
when(mUserManager.getEnabledProfiles(USER_ID_PRIMARY))
|
when(mUserManager.getEnabledProfiles(USER_ID_PRIMARY))
|
||||||
.thenReturn(Arrays.asList(
|
.thenReturn(Arrays.asList(
|
||||||
@@ -221,6 +215,9 @@ public final class DataManagerTest {
|
|||||||
verify(mShortcutServiceInternal).addShortcutChangeCallback(
|
verify(mShortcutServiceInternal).addShortcutChangeCallback(
|
||||||
mShortcutChangeCallbackCaptor.capture());
|
mShortcutChangeCallbackCaptor.capture());
|
||||||
mShortcutChangeCallback = mShortcutChangeCallbackCaptor.getValue();
|
mShortcutChangeCallback = mShortcutChangeCallbackCaptor.getValue();
|
||||||
|
|
||||||
|
verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), any());
|
||||||
|
mShutdownBroadcastReceiver = mBroadcastReceiverCaptor.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
@@ -459,7 +456,7 @@ public final class DataManagerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testShortcutNotUncachedIfSettingChanged() {
|
public void testShortcutNotUncachedIfNotificationChannelCreated() {
|
||||||
mDataManager.onUserUnlocked(USER_ID_PRIMARY);
|
mDataManager.onUserUnlocked(USER_ID_PRIMARY);
|
||||||
|
|
||||||
ShortcutInfo shortcut = buildShortcutInfo(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID,
|
ShortcutInfo shortcut = buildShortcutInfo(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID,
|
||||||
@@ -473,7 +470,6 @@ public final class DataManagerTest {
|
|||||||
shortcut.setCached();
|
shortcut.setCached();
|
||||||
mDataManager.addOrUpdateConversationInfo(shortcut);
|
mDataManager.addOrUpdateConversationInfo(shortcut);
|
||||||
|
|
||||||
mNotificationChannel.setImportantConversation(true);
|
|
||||||
listenerService.onNotificationChannelModified(TEST_PKG_NAME, UserHandle.of(USER_ID_PRIMARY),
|
listenerService.onNotificationChannelModified(TEST_PKG_NAME, UserHandle.of(USER_ID_PRIMARY),
|
||||||
mNotificationChannel, NOTIFICATION_CHANNEL_OR_GROUP_UPDATED);
|
mNotificationChannel, NOTIFICATION_CHANNEL_OR_GROUP_UPDATED);
|
||||||
|
|
||||||
@@ -530,7 +526,6 @@ public final class DataManagerTest {
|
|||||||
assertTrue(conversationInfo.isImportant());
|
assertTrue(conversationInfo.isImportant());
|
||||||
assertFalse(conversationInfo.isNotificationSilenced());
|
assertFalse(conversationInfo.isNotificationSilenced());
|
||||||
assertFalse(conversationInfo.isDemoted());
|
assertFalse(conversationInfo.isDemoted());
|
||||||
assertTrue(conversationInfo.isNotificationSettingChanged());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -562,6 +557,51 @@ public final class DataManagerTest {
|
|||||||
assertFalse(conversationInfo.isDemoted());
|
assertFalse(conversationInfo.isDemoted());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUncacheShortcutWhenShutdown() {
|
||||||
|
mDataManager.onUserUnlocked(USER_ID_PRIMARY);
|
||||||
|
|
||||||
|
ShortcutInfo shortcut = buildShortcutInfo(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID,
|
||||||
|
buildPerson());
|
||||||
|
mDataManager.addOrUpdateConversationInfo(shortcut);
|
||||||
|
|
||||||
|
NotificationListenerService listenerService =
|
||||||
|
mDataManager.getNotificationListenerServiceForTesting(USER_ID_PRIMARY);
|
||||||
|
|
||||||
|
listenerService.onNotificationPosted(mStatusBarNotification);
|
||||||
|
shortcut.setCached();
|
||||||
|
mDataManager.addOrUpdateConversationInfo(shortcut);
|
||||||
|
|
||||||
|
mShutdownBroadcastReceiver.onReceive(mContext, new Intent());
|
||||||
|
verify(mShortcutServiceInternal).uncacheShortcuts(
|
||||||
|
anyInt(), any(), eq(TEST_PKG_NAME),
|
||||||
|
eq(Collections.singletonList(TEST_SHORTCUT_ID)), eq(USER_ID_PRIMARY));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDoNotUncacheShortcutWhenShutdownIfNotificationChannelCreated() {
|
||||||
|
mDataManager.onUserUnlocked(USER_ID_PRIMARY);
|
||||||
|
|
||||||
|
ShortcutInfo shortcut = buildShortcutInfo(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID,
|
||||||
|
buildPerson());
|
||||||
|
mDataManager.addOrUpdateConversationInfo(shortcut);
|
||||||
|
|
||||||
|
NotificationListenerService listenerService =
|
||||||
|
mDataManager.getNotificationListenerServiceForTesting(USER_ID_PRIMARY);
|
||||||
|
|
||||||
|
listenerService.onNotificationPosted(mStatusBarNotification);
|
||||||
|
shortcut.setCached();
|
||||||
|
mDataManager.addOrUpdateConversationInfo(shortcut);
|
||||||
|
|
||||||
|
listenerService.onNotificationChannelModified(TEST_PKG_NAME, UserHandle.of(USER_ID_PRIMARY),
|
||||||
|
mNotificationChannel, NOTIFICATION_CHANNEL_OR_GROUP_UPDATED);
|
||||||
|
|
||||||
|
mShutdownBroadcastReceiver.onReceive(mContext, new Intent());
|
||||||
|
verify(mShortcutServiceInternal, never()).uncacheShortcuts(
|
||||||
|
anyInt(), any(), eq(TEST_PKG_NAME),
|
||||||
|
eq(Collections.singletonList(TEST_SHORTCUT_ID)), eq(USER_ID_PRIMARY));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testShortcutAddedOrUpdated() {
|
public void testShortcutAddedOrUpdated() {
|
||||||
mDataManager.onUserUnlocked(USER_ID_PRIMARY);
|
mDataManager.onUserUnlocked(USER_ID_PRIMARY);
|
||||||
@@ -721,6 +761,22 @@ public final class DataManagerTest {
|
|||||||
assertTrue(activeTimeSlots.isEmpty());
|
assertTrue(activeTimeSlots.isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPruneInactiveCachedShortcuts() {
|
||||||
|
mDataManager.onUserUnlocked(USER_ID_PRIMARY);
|
||||||
|
|
||||||
|
ShortcutInfo shortcut = buildShortcutInfo(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID,
|
||||||
|
buildPerson());
|
||||||
|
shortcut.setCached();
|
||||||
|
mDataManager.addOrUpdateConversationInfo(shortcut);
|
||||||
|
|
||||||
|
mDataManager.pruneDataForUser(USER_ID_PRIMARY, mCancellationSignal);
|
||||||
|
|
||||||
|
verify(mShortcutServiceInternal).uncacheShortcuts(
|
||||||
|
anyInt(), any(), eq(TEST_PKG_NAME),
|
||||||
|
eq(Collections.singletonList(TEST_SHORTCUT_ID)), eq(USER_ID_PRIMARY));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBackupAndRestoration()
|
public void testBackupAndRestoration()
|
||||||
throws IntentFilter.MalformedMimeTypeException {
|
throws IntentFilter.MalformedMimeTypeException {
|
||||||
|
|||||||
@@ -96,7 +96,6 @@ class MockScheduledExecutorService implements ScheduledExecutorService {
|
|||||||
@Override
|
@Override
|
||||||
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period,
|
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period,
|
||||||
TimeUnit unit) {
|
TimeUnit unit) {
|
||||||
Preconditions.checkState(unit == TimeUnit.MILLISECONDS);
|
|
||||||
return new MockScheduledFuture<>(command, period, unit);
|
return new MockScheduledFuture<>(command, period, unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user