Merge "When a profile is stopped, remove pending snoozes" into tm-qpr-dev am: bd945c1115
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19213106 Change-Id: I8f7d4a38c55bbdda380376ab02ed438e787e749e Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -1794,6 +1794,7 @@ public class NotificationManagerService extends SystemService {
|
|||||||
if (userHandle >= 0) {
|
if (userHandle >= 0) {
|
||||||
cancelAllNotificationsInt(MY_UID, MY_PID, null, null, 0, 0, true, userHandle,
|
cancelAllNotificationsInt(MY_UID, MY_PID, null, null, 0, 0, true, userHandle,
|
||||||
REASON_PROFILE_TURNED_OFF, null);
|
REASON_PROFILE_TURNED_OFF, null);
|
||||||
|
mSnoozeHelper.clearData(userHandle);
|
||||||
}
|
}
|
||||||
} else if (action.equals(Intent.ACTION_USER_PRESENT)) {
|
} else if (action.equals(Intent.ACTION_USER_PRESENT)) {
|
||||||
// turn off LED when user passes through lock screen
|
// turn off LED when user passes through lock screen
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
package com.android.server.notification;
|
package com.android.server.notification;
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.UserIdInt;
|
|
||||||
import android.app.AlarmManager;
|
import android.app.AlarmManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
@@ -25,7 +24,6 @@ import android.content.Intent;
|
|||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.SystemClock;
|
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.service.notification.StatusBarNotification;
|
import android.service.notification.StatusBarNotification;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
@@ -38,18 +36,15 @@ import android.util.TypedXmlSerializer;
|
|||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.internal.logging.MetricsLogger;
|
import com.android.internal.logging.MetricsLogger;
|
||||||
import com.android.internal.logging.nano.MetricsProto;
|
import com.android.internal.logging.nano.MetricsProto;
|
||||||
import com.android.internal.util.XmlUtils;
|
|
||||||
import com.android.server.pm.PackageManagerService;
|
import com.android.server.pm.PackageManagerService;
|
||||||
|
|
||||||
import org.xmlpull.v1.XmlPullParser;
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
import org.xmlpull.v1.XmlPullParserException;
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
import org.xmlpull.v1.XmlSerializer;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -59,7 +54,7 @@ import java.util.Set;
|
|||||||
/**
|
/**
|
||||||
* NotificationManagerService helper for handling snoozed notifications.
|
* NotificationManagerService helper for handling snoozed notifications.
|
||||||
*/
|
*/
|
||||||
public class SnoozeHelper {
|
public final class SnoozeHelper {
|
||||||
public static final int XML_SNOOZED_NOTIFICATION_VERSION = 1;
|
public static final int XML_SNOOZED_NOTIFICATION_VERSION = 1;
|
||||||
|
|
||||||
static final int CONCURRENT_SNOOZE_LIMIT = 500;
|
static final int CONCURRENT_SNOOZE_LIMIT = 500;
|
||||||
@@ -68,8 +63,6 @@ public class SnoozeHelper {
|
|||||||
|
|
||||||
private static final String XML_SNOOZED_NOTIFICATION = "notification";
|
private static final String XML_SNOOZED_NOTIFICATION = "notification";
|
||||||
private static final String XML_SNOOZED_NOTIFICATION_CONTEXT = "context";
|
private static final String XML_SNOOZED_NOTIFICATION_CONTEXT = "context";
|
||||||
private static final String XML_SNOOZED_NOTIFICATION_PKG = "pkg";
|
|
||||||
private static final String XML_SNOOZED_NOTIFICATION_USER_ID = "user-id";
|
|
||||||
private static final String XML_SNOOZED_NOTIFICATION_KEY = "key";
|
private static final String XML_SNOOZED_NOTIFICATION_KEY = "key";
|
||||||
//the time the snoozed notification should be reposted
|
//the time the snoozed notification should be reposted
|
||||||
private static final String XML_SNOOZED_NOTIFICATION_TIME = "time";
|
private static final String XML_SNOOZED_NOTIFICATION_TIME = "time";
|
||||||
@@ -91,24 +84,19 @@ public class SnoozeHelper {
|
|||||||
private AlarmManager mAm;
|
private AlarmManager mAm;
|
||||||
private final ManagedServices.UserProfiles mUserProfiles;
|
private final ManagedServices.UserProfiles mUserProfiles;
|
||||||
|
|
||||||
// User id | package name : notification key : record.
|
// notification key : record.
|
||||||
private ArrayMap<String, ArrayMap<String, NotificationRecord>>
|
private ArrayMap<String, NotificationRecord> mSnoozedNotifications = new ArrayMap<>();
|
||||||
mSnoozedNotifications = new ArrayMap<>();
|
// notification key : time-milliseconds .
|
||||||
// User id | package name : notification key : time-milliseconds .
|
|
||||||
// This member stores persisted snoozed notification trigger times. it persists through reboots
|
// This member stores persisted snoozed notification trigger times. it persists through reboots
|
||||||
// It should have the notifications that haven't expired or re-posted yet
|
// It should have the notifications that haven't expired or re-posted yet
|
||||||
private final ArrayMap<String, ArrayMap<String, Long>>
|
private final ArrayMap<String, Long> mPersistedSnoozedNotifications = new ArrayMap<>();
|
||||||
mPersistedSnoozedNotifications = new ArrayMap<>();
|
// notification key : creation ID.
|
||||||
// User id | package name : notification key : creation ID .
|
|
||||||
// This member stores persisted snoozed notification trigger context for the assistant
|
// This member stores persisted snoozed notification trigger context for the assistant
|
||||||
// it persists through reboots.
|
// it persists through reboots.
|
||||||
// It should have the notifications that haven't expired or re-posted yet
|
// It should have the notifications that haven't expired or re-posted yet
|
||||||
private final ArrayMap<String, ArrayMap<String, String>>
|
private final ArrayMap<String, String>
|
||||||
mPersistedSnoozedNotificationsWithContext = new ArrayMap<>();
|
mPersistedSnoozedNotificationsWithContext = new ArrayMap<>();
|
||||||
// notification key : package.
|
|
||||||
private ArrayMap<String, String> mPackages = new ArrayMap<>();
|
|
||||||
// key : userId
|
|
||||||
private ArrayMap<String, Integer> mUsers = new ArrayMap<>();
|
|
||||||
private Callback mCallback;
|
private Callback mCallback;
|
||||||
|
|
||||||
private final Object mLock = new Object();
|
private final Object mLock = new Object();
|
||||||
@@ -125,21 +113,9 @@ public class SnoozeHelper {
|
|||||||
mUserProfiles = userProfiles;
|
mUserProfiles = userProfiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getPkgKey(@UserIdInt int userId, String pkg) {
|
|
||||||
return userId + "|" + pkg;
|
|
||||||
}
|
|
||||||
|
|
||||||
void cleanupPersistedContext(String key){
|
|
||||||
synchronized (mLock) {
|
|
||||||
int userId = mUsers.get(key);
|
|
||||||
String pkg = mPackages.get(key);
|
|
||||||
removeRecordLocked(pkg, key, userId, mPersistedSnoozedNotificationsWithContext);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean canSnooze(int numberToSnooze) {
|
protected boolean canSnooze(int numberToSnooze) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
if ((mPackages.size() + numberToSnooze) > CONCURRENT_SNOOZE_LIMIT) {
|
if ((mSnoozedNotifications.size() + numberToSnooze) > CONCURRENT_SNOOZE_LIMIT) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -150,11 +126,7 @@ public class SnoozeHelper {
|
|||||||
protected Long getSnoozeTimeForUnpostedNotification(int userId, String pkg, String key) {
|
protected Long getSnoozeTimeForUnpostedNotification(int userId, String pkg, String key) {
|
||||||
Long time = null;
|
Long time = null;
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
ArrayMap<String, Long> snoozed =
|
time = mPersistedSnoozedNotifications.get(key);
|
||||||
mPersistedSnoozedNotifications.get(getPkgKey(userId, pkg));
|
|
||||||
if (snoozed != null) {
|
|
||||||
time = snoozed.get(key);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (time == null) {
|
if (time == null) {
|
||||||
time = 0L;
|
time = 0L;
|
||||||
@@ -164,29 +136,26 @@ public class SnoozeHelper {
|
|||||||
|
|
||||||
protected String getSnoozeContextForUnpostedNotification(int userId, String pkg, String key) {
|
protected String getSnoozeContextForUnpostedNotification(int userId, String pkg, String key) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
ArrayMap<String, String> snoozed =
|
return mPersistedSnoozedNotificationsWithContext.get(key);
|
||||||
mPersistedSnoozedNotificationsWithContext.get(getPkgKey(userId, pkg));
|
|
||||||
if (snoozed != null) {
|
|
||||||
return snoozed.get(key);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isSnoozed(int userId, String pkg, String key) {
|
protected boolean isSnoozed(int userId, String pkg, String key) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
return mSnoozedNotifications.containsKey(getPkgKey(userId, pkg))
|
return mSnoozedNotifications.containsKey(key);
|
||||||
&& mSnoozedNotifications.get(getPkgKey(userId, pkg)).containsKey(key);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Collection<NotificationRecord> getSnoozed(int userId, String pkg) {
|
protected Collection<NotificationRecord> getSnoozed(int userId, String pkg) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
if (mSnoozedNotifications.containsKey(getPkgKey(userId, pkg))) {
|
ArrayList snoozed = new ArrayList();
|
||||||
return mSnoozedNotifications.get(getPkgKey(userId, pkg)).values();
|
for (NotificationRecord r : mSnoozedNotifications.values()) {
|
||||||
|
if (r.getUserId() == userId && r.getSbn().getPackageName().equals(pkg)) {
|
||||||
|
snoozed.add(r);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return snoozed;
|
||||||
}
|
}
|
||||||
return Collections.EMPTY_LIST;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@@ -194,15 +163,11 @@ public class SnoozeHelper {
|
|||||||
String groupKey, Integer userId) {
|
String groupKey, Integer userId) {
|
||||||
ArrayList<NotificationRecord> records = new ArrayList<>();
|
ArrayList<NotificationRecord> records = new ArrayList<>();
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
ArrayMap<String, NotificationRecord> allRecords =
|
for (int i = 0; i < mSnoozedNotifications.size(); i++) {
|
||||||
mSnoozedNotifications.get(getPkgKey(userId, pkg));
|
NotificationRecord r = mSnoozedNotifications.valueAt(i);
|
||||||
if (allRecords != null) {
|
if (r.getSbn().getPackageName().equals(pkg) && r.getUserId() == userId
|
||||||
for (int i = 0; i < allRecords.size(); i++) {
|
&& Objects.equals(r.getSbn().getGroup(), groupKey)) {
|
||||||
NotificationRecord r = allRecords.valueAt(i);
|
records.add(r);
|
||||||
String currentGroupKey = r.getSbn().getGroup();
|
|
||||||
if (Objects.equals(currentGroupKey, groupKey)) {
|
|
||||||
records.add(r);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -211,31 +176,16 @@ public class SnoozeHelper {
|
|||||||
|
|
||||||
protected NotificationRecord getNotification(String key) {
|
protected NotificationRecord getNotification(String key) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
if (!mUsers.containsKey(key) || !mPackages.containsKey(key)) {
|
return mSnoozedNotifications.get(key);
|
||||||
Slog.w(TAG, "Snoozed data sets no longer agree for " + key);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
int userId = mUsers.get(key);
|
|
||||||
String pkg = mPackages.get(key);
|
|
||||||
ArrayMap<String, NotificationRecord> snoozed =
|
|
||||||
mSnoozedNotifications.get(getPkgKey(userId, pkg));
|
|
||||||
if (snoozed == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return snoozed.get(key);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected @NonNull List<NotificationRecord> getSnoozed() {
|
protected @NonNull List<NotificationRecord> getSnoozed() {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
// caller filters records based on the current user profiles and listener access, so just
|
// caller filters records based on the current user profiles and listener access,
|
||||||
// return everything
|
// so just return everything
|
||||||
List<NotificationRecord> snoozed = new ArrayList<>();
|
List<NotificationRecord> snoozed = new ArrayList<>();
|
||||||
for (String userPkgKey : mSnoozedNotifications.keySet()) {
|
snoozed.addAll(mSnoozedNotifications.values());
|
||||||
ArrayMap<String, NotificationRecord> snoozedRecords =
|
|
||||||
mSnoozedNotifications.get(userPkgKey);
|
|
||||||
snoozed.addAll(snoozedRecords.values());
|
|
||||||
}
|
|
||||||
return snoozed;
|
return snoozed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -244,15 +194,13 @@ public class SnoozeHelper {
|
|||||||
* Snoozes a notification and schedules an alarm to repost at that time.
|
* Snoozes a notification and schedules an alarm to repost at that time.
|
||||||
*/
|
*/
|
||||||
protected void snooze(NotificationRecord record, long duration) {
|
protected void snooze(NotificationRecord record, long duration) {
|
||||||
String pkg = record.getSbn().getPackageName();
|
|
||||||
String key = record.getKey();
|
String key = record.getKey();
|
||||||
int userId = record.getUser().getIdentifier();
|
|
||||||
|
|
||||||
snooze(record);
|
snooze(record);
|
||||||
scheduleRepost(pkg, key, userId, duration);
|
scheduleRepost(key, duration);
|
||||||
Long activateAt = System.currentTimeMillis() + duration;
|
Long activateAt = System.currentTimeMillis() + duration;
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
storeRecordLocked(pkg, key, userId, mPersistedSnoozedNotifications, activateAt);
|
mPersistedSnoozedNotifications.put(key, activateAt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,66 +208,33 @@ public class SnoozeHelper {
|
|||||||
* Records a snoozed notification.
|
* Records a snoozed notification.
|
||||||
*/
|
*/
|
||||||
protected void snooze(NotificationRecord record, String contextId) {
|
protected void snooze(NotificationRecord record, String contextId) {
|
||||||
int userId = record.getUser().getIdentifier();
|
|
||||||
if (contextId != null) {
|
if (contextId != null) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
storeRecordLocked(record.getSbn().getPackageName(), record.getKey(),
|
mPersistedSnoozedNotificationsWithContext.put(record.getKey(), contextId);
|
||||||
userId, mPersistedSnoozedNotificationsWithContext, contextId);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
snooze(record);
|
snooze(record);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void snooze(NotificationRecord record) {
|
private void snooze(NotificationRecord record) {
|
||||||
int userId = record.getUser().getIdentifier();
|
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Slog.d(TAG, "Snoozing " + record.getKey());
|
Slog.d(TAG, "Snoozing " + record.getKey());
|
||||||
}
|
}
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
storeRecordLocked(record.getSbn().getPackageName(), record.getKey(),
|
mSnoozedNotifications.put(record.getKey(), record);
|
||||||
userId, mSnoozedNotifications, record);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> void storeRecordLocked(String pkg, String key, Integer userId,
|
|
||||||
ArrayMap<String, ArrayMap<String, T>> targets, T object) {
|
|
||||||
|
|
||||||
mPackages.put(key, pkg);
|
|
||||||
mUsers.put(key, userId);
|
|
||||||
ArrayMap<String, T> keyToValue = targets.get(getPkgKey(userId, pkg));
|
|
||||||
if (keyToValue == null) {
|
|
||||||
keyToValue = new ArrayMap<>();
|
|
||||||
}
|
|
||||||
keyToValue.put(key, object);
|
|
||||||
targets.put(getPkgKey(userId, pkg), keyToValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
private <T> T removeRecordLocked(String pkg, String key, Integer userId,
|
|
||||||
ArrayMap<String, ArrayMap<String, T>> targets) {
|
|
||||||
T object = null;
|
|
||||||
ArrayMap<String, T> keyToValue = targets.get(getPkgKey(userId, pkg));
|
|
||||||
if (keyToValue == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
object = keyToValue.remove(key);
|
|
||||||
if (keyToValue.size() == 0) {
|
|
||||||
targets.remove(getPkgKey(userId, pkg));
|
|
||||||
}
|
|
||||||
return object;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean cancel(int userId, String pkg, String tag, int id) {
|
protected boolean cancel(int userId, String pkg, String tag, int id) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
ArrayMap<String, NotificationRecord> recordsForPkg =
|
final Set<Map.Entry<String, NotificationRecord>> records =
|
||||||
mSnoozedNotifications.get(getPkgKey(userId, pkg));
|
mSnoozedNotifications.entrySet();
|
||||||
if (recordsForPkg != null) {
|
for (Map.Entry<String, NotificationRecord> record : records) {
|
||||||
final Set<Map.Entry<String, NotificationRecord>> records = recordsForPkg.entrySet();
|
final StatusBarNotification sbn = record.getValue().getSbn();
|
||||||
for (Map.Entry<String, NotificationRecord> record : records) {
|
if (sbn.getPackageName().equals(pkg) && sbn.getUserId() == userId
|
||||||
final StatusBarNotification sbn = record.getValue().getSbn();
|
&& Objects.equals(sbn.getTag(), tag) && sbn.getId() == id) {
|
||||||
if (Objects.equals(sbn.getTag(), tag) && sbn.getId() == id) {
|
record.getValue().isCanceled = true;
|
||||||
record.getValue().isCanceled = true;
|
return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -336,11 +251,9 @@ public class SnoozeHelper {
|
|||||||
if (includeCurrentProfiles) {
|
if (includeCurrentProfiles) {
|
||||||
userIds = mUserProfiles.getCurrentProfileIds();
|
userIds = mUserProfiles.getCurrentProfileIds();
|
||||||
}
|
}
|
||||||
for (ArrayMap<String, NotificationRecord> snoozedRecords : mSnoozedNotifications.values()) {
|
for (NotificationRecord r : mSnoozedNotifications.values()) {
|
||||||
for (NotificationRecord r : snoozedRecords.values()) {
|
if (userIds.binarySearch(r.getUserId()) >= 0) {
|
||||||
if (userIds.binarySearch(r.getUserId()) >= 0) {
|
r.isCanceled = true;
|
||||||
r.isCanceled = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -348,14 +261,12 @@ public class SnoozeHelper {
|
|||||||
|
|
||||||
protected boolean cancel(int userId, String pkg) {
|
protected boolean cancel(int userId, String pkg) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
ArrayMap<String, NotificationRecord> records =
|
int n = mSnoozedNotifications.size();
|
||||||
mSnoozedNotifications.get(getPkgKey(userId, pkg));
|
for (int i = 0; i < n; i++) {
|
||||||
if (records == null) {
|
final NotificationRecord r = mSnoozedNotifications.valueAt(i);
|
||||||
return false;
|
if (r.getSbn().getPackageName().equals(pkg) && r.getUserId() == userId) {
|
||||||
}
|
r.isCanceled = true;
|
||||||
int N = records.size();
|
}
|
||||||
for (int i = 0; i < N; i++) {
|
|
||||||
records.valueAt(i).isCanceled = true;
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -366,20 +277,17 @@ public class SnoozeHelper {
|
|||||||
*/
|
*/
|
||||||
protected void update(int userId, NotificationRecord record) {
|
protected void update(int userId, NotificationRecord record) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
ArrayMap<String, NotificationRecord> records =
|
if (mSnoozedNotifications.containsKey(record.getKey())) {
|
||||||
mSnoozedNotifications.get(getPkgKey(userId, record.getSbn().getPackageName()));
|
mSnoozedNotifications.put(record.getKey(), record);
|
||||||
if (records == null) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
records.put(record.getKey(), record);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void repost(String key, boolean muteOnReturn) {
|
protected void repost(String key, boolean muteOnReturn) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
Integer userId = mUsers.get(key);
|
final NotificationRecord r = mSnoozedNotifications.get(key);
|
||||||
if (userId != null) {
|
if (r != null) {
|
||||||
repost(key, userId, muteOnReturn);
|
repost(key, r.getUserId(), muteOnReturn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -387,43 +295,30 @@ public class SnoozeHelper {
|
|||||||
protected void repost(String key, int userId, boolean muteOnReturn) {
|
protected void repost(String key, int userId, boolean muteOnReturn) {
|
||||||
NotificationRecord record;
|
NotificationRecord record;
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
final String pkg = mPackages.remove(key);
|
mPersistedSnoozedNotifications.remove(key);
|
||||||
mUsers.remove(key);
|
mPersistedSnoozedNotificationsWithContext.remove(key);
|
||||||
removeRecordLocked(pkg, key, userId, mPersistedSnoozedNotifications);
|
record = mSnoozedNotifications.remove(key);
|
||||||
removeRecordLocked(pkg, key, userId, mPersistedSnoozedNotificationsWithContext);
|
|
||||||
ArrayMap<String, NotificationRecord> records =
|
|
||||||
mSnoozedNotifications.get(getPkgKey(userId, pkg));
|
|
||||||
if (records == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
record = records.remove(key);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (record != null && !record.isCanceled) {
|
if (record != null && !record.isCanceled) {
|
||||||
final PendingIntent pi = createPendingIntent(
|
final PendingIntent pi = createPendingIntent(record.getKey());
|
||||||
record.getSbn().getPackageName(), record.getKey(), userId);
|
|
||||||
mAm.cancel(pi);
|
mAm.cancel(pi);
|
||||||
MetricsLogger.action(record.getLogMaker()
|
MetricsLogger.action(record.getLogMaker()
|
||||||
.setCategory(MetricsProto.MetricsEvent.NOTIFICATION_SNOOZED)
|
.setCategory(MetricsProto.MetricsEvent.NOTIFICATION_SNOOZED)
|
||||||
.setType(MetricsProto.MetricsEvent.TYPE_OPEN));
|
.setType(MetricsProto.MetricsEvent.TYPE_OPEN));
|
||||||
mCallback.repost(userId, record, muteOnReturn);
|
mCallback.repost(record.getUserId(), record, muteOnReturn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void repostGroupSummary(String pkg, int userId, String groupKey) {
|
protected void repostGroupSummary(String pkg, int userId, String groupKey) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
ArrayMap<String, NotificationRecord> recordsByKey
|
|
||||||
= mSnoozedNotifications.get(getPkgKey(userId, pkg));
|
|
||||||
if (recordsByKey == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String groupSummaryKey = null;
|
String groupSummaryKey = null;
|
||||||
int N = recordsByKey.size();
|
int n = mSnoozedNotifications.size();
|
||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
final NotificationRecord potentialGroupSummary = recordsByKey.valueAt(i);
|
final NotificationRecord potentialGroupSummary = mSnoozedNotifications.valueAt(i);
|
||||||
if (potentialGroupSummary.getSbn().isGroup()
|
if (potentialGroupSummary.getSbn().getPackageName().equals(pkg)
|
||||||
|
&& potentialGroupSummary.getUserId() == userId
|
||||||
|
&& potentialGroupSummary.getSbn().isGroup()
|
||||||
&& potentialGroupSummary.getNotification().isGroupSummary()
|
&& potentialGroupSummary.getNotification().isGroupSummary()
|
||||||
&& groupKey.equals(potentialGroupSummary.getGroupKey())) {
|
&& groupKey.equals(potentialGroupSummary.getGroupKey())) {
|
||||||
groupSummaryKey = potentialGroupSummary.getKey();
|
groupSummaryKey = potentialGroupSummary.getKey();
|
||||||
@@ -432,16 +327,14 @@ public class SnoozeHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (groupSummaryKey != null) {
|
if (groupSummaryKey != null) {
|
||||||
NotificationRecord record = recordsByKey.remove(groupSummaryKey);
|
NotificationRecord record = mSnoozedNotifications.remove(groupSummaryKey);
|
||||||
mPackages.remove(groupSummaryKey);
|
|
||||||
mUsers.remove(groupSummaryKey);
|
|
||||||
|
|
||||||
if (record != null && !record.isCanceled) {
|
if (record != null && !record.isCanceled) {
|
||||||
Runnable runnable = () -> {
|
Runnable runnable = () -> {
|
||||||
MetricsLogger.action(record.getLogMaker()
|
MetricsLogger.action(record.getLogMaker()
|
||||||
.setCategory(MetricsProto.MetricsEvent.NOTIFICATION_SNOOZED)
|
.setCategory(MetricsProto.MetricsEvent.NOTIFICATION_SNOOZED)
|
||||||
.setType(MetricsProto.MetricsEvent.TYPE_OPEN));
|
.setType(MetricsProto.MetricsEvent.TYPE_OPEN));
|
||||||
mCallback.repost(userId, record, false);
|
mCallback.repost(record.getUserId(), record, false);
|
||||||
};
|
};
|
||||||
runnable.run();
|
runnable.run();
|
||||||
}
|
}
|
||||||
@@ -451,20 +344,17 @@ public class SnoozeHelper {
|
|||||||
|
|
||||||
protected void clearData(int userId, String pkg) {
|
protected void clearData(int userId, String pkg) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
ArrayMap<String, NotificationRecord> records =
|
int n = mSnoozedNotifications.size();
|
||||||
mSnoozedNotifications.get(getPkgKey(userId, pkg));
|
for (int i = n - 1; i >= 0; i--) {
|
||||||
if (records == null) {
|
final NotificationRecord record = mSnoozedNotifications.valueAt(i);
|
||||||
return;
|
if (record.getUserId() == userId && record.getSbn().getPackageName().equals(pkg)) {
|
||||||
}
|
mSnoozedNotifications.removeAt(i);
|
||||||
for (int i = records.size() - 1; i >= 0; i--) {
|
mPersistedSnoozedNotificationsWithContext.remove(record.getKey());
|
||||||
final NotificationRecord r = records.removeAt(i);
|
mPersistedSnoozedNotifications.remove(record.getKey());
|
||||||
if (r != null) {
|
|
||||||
mPackages.remove(r.getKey());
|
|
||||||
mUsers.remove(r.getKey());
|
|
||||||
Runnable runnable = () -> {
|
Runnable runnable = () -> {
|
||||||
final PendingIntent pi = createPendingIntent(pkg, r.getKey(), userId);
|
final PendingIntent pi = createPendingIntent(record.getKey());
|
||||||
mAm.cancel(pi);
|
mAm.cancel(pi);
|
||||||
MetricsLogger.action(r.getLogMaker()
|
MetricsLogger.action(record.getLogMaker()
|
||||||
.setCategory(MetricsProto.MetricsEvent.NOTIFICATION_SNOOZED)
|
.setCategory(MetricsProto.MetricsEvent.NOTIFICATION_SNOOZED)
|
||||||
.setType(MetricsProto.MetricsEvent.TYPE_DISMISS));
|
.setType(MetricsProto.MetricsEvent.TYPE_DISMISS));
|
||||||
};
|
};
|
||||||
@@ -474,47 +364,61 @@ public class SnoozeHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private PendingIntent createPendingIntent(String pkg, String key, int userId) {
|
protected void clearData(int userId) {
|
||||||
|
synchronized (mLock) {
|
||||||
|
int n = mSnoozedNotifications.size();
|
||||||
|
for (int i = n - 1; i >= 0; i--) {
|
||||||
|
final NotificationRecord record = mSnoozedNotifications.valueAt(i);
|
||||||
|
if (record.getUserId() == userId) {
|
||||||
|
mSnoozedNotifications.removeAt(i);
|
||||||
|
mPersistedSnoozedNotificationsWithContext.remove(record.getKey());
|
||||||
|
mPersistedSnoozedNotifications.remove(record.getKey());
|
||||||
|
|
||||||
|
Runnable runnable = () -> {
|
||||||
|
final PendingIntent pi = createPendingIntent(record.getKey());
|
||||||
|
mAm.cancel(pi);
|
||||||
|
MetricsLogger.action(record.getLogMaker()
|
||||||
|
.setCategory(MetricsProto.MetricsEvent.NOTIFICATION_SNOOZED)
|
||||||
|
.setType(MetricsProto.MetricsEvent.TYPE_DISMISS));
|
||||||
|
};
|
||||||
|
runnable.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private PendingIntent createPendingIntent(String key) {
|
||||||
return PendingIntent.getBroadcast(mContext,
|
return PendingIntent.getBroadcast(mContext,
|
||||||
REQUEST_CODE_REPOST,
|
REQUEST_CODE_REPOST,
|
||||||
new Intent(REPOST_ACTION)
|
new Intent(REPOST_ACTION)
|
||||||
.setPackage(PackageManagerService.PLATFORM_PACKAGE_NAME)
|
.setPackage(PackageManagerService.PLATFORM_PACKAGE_NAME)
|
||||||
.setData(new Uri.Builder().scheme(REPOST_SCHEME).appendPath(key).build())
|
.setData(new Uri.Builder().scheme(REPOST_SCHEME).appendPath(key).build())
|
||||||
.addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
|
.addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
|
||||||
.putExtra(EXTRA_KEY, key)
|
.putExtra(EXTRA_KEY, key),
|
||||||
.putExtra(EXTRA_USER_ID, userId),
|
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
|
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void scheduleRepostsForPersistedNotifications(long currentTime) {
|
public void scheduleRepostsForPersistedNotifications(long currentTime) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
for (ArrayMap<String, Long> snoozed : mPersistedSnoozedNotifications.values()) {
|
for (int i = 0; i < mPersistedSnoozedNotifications.size(); i++) {
|
||||||
for (int i = 0; i < snoozed.size(); i++) {
|
String key = mPersistedSnoozedNotifications.keyAt(i);
|
||||||
String key = snoozed.keyAt(i);
|
Long time = mPersistedSnoozedNotifications.valueAt(i);
|
||||||
Long time = snoozed.valueAt(i);
|
if (time != null && time > currentTime) {
|
||||||
String pkg = mPackages.get(key);
|
scheduleRepostAtTime(key, time);
|
||||||
Integer userId = mUsers.get(key);
|
|
||||||
if (time == null || pkg == null || userId == null) {
|
|
||||||
Slog.w(TAG, "data out of sync: " + time + "|" + pkg + "|" + userId);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (time != null && time > currentTime) {
|
|
||||||
scheduleRepostAtTime(pkg, key, userId, time);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void scheduleRepost(String pkg, String key, int userId, long duration) {
|
private void scheduleRepost(String key, long duration) {
|
||||||
scheduleRepostAtTime(pkg, key, userId, System.currentTimeMillis() + duration);
|
scheduleRepostAtTime(key, System.currentTimeMillis() + duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void scheduleRepostAtTime(String pkg, String key, int userId, long time) {
|
private void scheduleRepostAtTime(String key, long time) {
|
||||||
Runnable runnable = () -> {
|
Runnable runnable = () -> {
|
||||||
final long identity = Binder.clearCallingIdentity();
|
final long identity = Binder.clearCallingIdentity();
|
||||||
try {
|
try {
|
||||||
final PendingIntent pi = createPendingIntent(pkg, key, userId);
|
final PendingIntent pi = createPendingIntent(key);
|
||||||
mAm.cancel(pi);
|
mAm.cancel(pi);
|
||||||
if (DEBUG) Slog.d(TAG, "Scheduling evaluate for " + new Date(time));
|
if (DEBUG) Slog.d(TAG, "Scheduling evaluate for " + new Date(time));
|
||||||
mAm.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, time, pi);
|
mAm.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, time, pi);
|
||||||
@@ -528,37 +432,14 @@ public class SnoozeHelper {
|
|||||||
public void dump(PrintWriter pw, NotificationManagerService.DumpFilter filter) {
|
public void dump(PrintWriter pw, NotificationManagerService.DumpFilter filter) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
pw.println("\n Snoozed notifications:");
|
pw.println("\n Snoozed notifications:");
|
||||||
for (String userPkgKey : mSnoozedNotifications.keySet()) {
|
for (String key : mSnoozedNotifications.keySet()) {
|
||||||
pw.print(INDENT);
|
pw.print(INDENT);
|
||||||
pw.println("key: " + userPkgKey);
|
pw.println("key: " + key);
|
||||||
ArrayMap<String, NotificationRecord> snoozedRecords =
|
|
||||||
mSnoozedNotifications.get(userPkgKey);
|
|
||||||
Set<String> snoozedKeys = snoozedRecords.keySet();
|
|
||||||
for (String key : snoozedKeys) {
|
|
||||||
pw.print(INDENT);
|
|
||||||
pw.print(INDENT);
|
|
||||||
pw.print(INDENT);
|
|
||||||
pw.println(key);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
pw.println("\n Pending snoozed notifications");
|
pw.println("\n Pending snoozed notifications");
|
||||||
for (String userPkgKey : mPersistedSnoozedNotifications.keySet()) {
|
for (String key : mPersistedSnoozedNotifications.keySet()) {
|
||||||
pw.print(INDENT);
|
pw.print(INDENT);
|
||||||
pw.println("key: " + userPkgKey);
|
pw.println("key: " + key + " until: " + mPersistedSnoozedNotifications.get(key));
|
||||||
ArrayMap<String, Long> snoozedRecords =
|
|
||||||
mPersistedSnoozedNotifications.get(userPkgKey);
|
|
||||||
if (snoozedRecords == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Set<String> snoozedKeys = snoozedRecords.keySet();
|
|
||||||
for (String key : snoozedKeys) {
|
|
||||||
pw.print(INDENT);
|
|
||||||
pw.print(INDENT);
|
|
||||||
pw.print(INDENT);
|
|
||||||
pw.print(key);
|
|
||||||
pw.print(INDENT);
|
|
||||||
pw.println(snoozedRecords.get(key));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -589,37 +470,22 @@ public class SnoozeHelper {
|
|||||||
void insert(T t) throws IOException;
|
void insert(T t) throws IOException;
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> void writeXml(TypedXmlSerializer out,
|
private <T> void writeXml(TypedXmlSerializer out, ArrayMap<String, T> targets, String tag,
|
||||||
ArrayMap<String, ArrayMap<String, T>> targets, String tag,
|
Inserter<T> attributeInserter) throws IOException {
|
||||||
Inserter<T> attributeInserter)
|
for (int j = 0; j < targets.size(); j++) {
|
||||||
throws IOException {
|
String key = targets.keyAt(j);
|
||||||
final int M = targets.size();
|
|
||||||
for (int i = 0; i < M; i++) {
|
|
||||||
// T is a String (snoozed until context) or Long (snoozed until time)
|
// T is a String (snoozed until context) or Long (snoozed until time)
|
||||||
ArrayMap<String, T> keyToValue = targets.valueAt(i);
|
T value = targets.valueAt(j);
|
||||||
for (int j = 0; j < keyToValue.size(); j++) {
|
|
||||||
String key = keyToValue.keyAt(j);
|
|
||||||
T value = keyToValue.valueAt(j);
|
|
||||||
String pkg = mPackages.get(key);
|
|
||||||
Integer userId = mUsers.get(key);
|
|
||||||
|
|
||||||
if (pkg == null || userId == null) {
|
out.startTag(null, tag);
|
||||||
Slog.w(TAG, "pkg " + pkg + " or user " + userId + " missing for " + key);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
out.startTag(null, tag);
|
attributeInserter.insert(value);
|
||||||
|
|
||||||
attributeInserter.insert(value);
|
out.attributeInt(null, XML_SNOOZED_NOTIFICATION_VERSION_LABEL,
|
||||||
|
XML_SNOOZED_NOTIFICATION_VERSION);
|
||||||
|
out.attribute(null, XML_SNOOZED_NOTIFICATION_KEY, key);
|
||||||
|
|
||||||
out.attributeInt(null, XML_SNOOZED_NOTIFICATION_VERSION_LABEL,
|
out.endTag(null, tag);
|
||||||
XML_SNOOZED_NOTIFICATION_VERSION);
|
|
||||||
out.attribute(null, XML_SNOOZED_NOTIFICATION_KEY, key);
|
|
||||||
out.attribute(null, XML_SNOOZED_NOTIFICATION_PKG, pkg);
|
|
||||||
out.attributeInt(null, XML_SNOOZED_NOTIFICATION_USER_ID, userId);
|
|
||||||
|
|
||||||
out.endTag(null, tag);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -639,16 +505,12 @@ public class SnoozeHelper {
|
|||||||
== XML_SNOOZED_NOTIFICATION_VERSION) {
|
== XML_SNOOZED_NOTIFICATION_VERSION) {
|
||||||
try {
|
try {
|
||||||
final String key = parser.getAttributeValue(null, XML_SNOOZED_NOTIFICATION_KEY);
|
final String key = parser.getAttributeValue(null, XML_SNOOZED_NOTIFICATION_KEY);
|
||||||
final String pkg = parser.getAttributeValue(null, XML_SNOOZED_NOTIFICATION_PKG);
|
|
||||||
final int userId = parser.getAttributeInt(
|
|
||||||
null, XML_SNOOZED_NOTIFICATION_USER_ID, UserHandle.USER_ALL);
|
|
||||||
if (tag.equals(XML_SNOOZED_NOTIFICATION)) {
|
if (tag.equals(XML_SNOOZED_NOTIFICATION)) {
|
||||||
final Long time = parser.getAttributeLong(
|
final Long time = parser.getAttributeLong(
|
||||||
null, XML_SNOOZED_NOTIFICATION_TIME, 0);
|
null, XML_SNOOZED_NOTIFICATION_TIME, 0);
|
||||||
if (time > currentTime) { //only read new stuff
|
if (time > currentTime) { //only read new stuff
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
storeRecordLocked(
|
mPersistedSnoozedNotifications.put(key, time);
|
||||||
pkg, key, userId, mPersistedSnoozedNotifications, time);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -656,9 +518,7 @@ public class SnoozeHelper {
|
|||||||
final String creationId = parser.getAttributeValue(
|
final String creationId = parser.getAttributeValue(
|
||||||
null, XML_SNOOZED_NOTIFICATION_CONTEXT_ID);
|
null, XML_SNOOZED_NOTIFICATION_CONTEXT_ID);
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
storeRecordLocked(
|
mPersistedSnoozedNotificationsWithContext.put(key, creationId);
|
||||||
pkg, key, userId, mPersistedSnoozedNotificationsWithContext,
|
|
||||||
creationId);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import static com.android.server.notification.SnoozeHelper.EXTRA_KEY;
|
|||||||
|
|
||||||
import static junit.framework.Assert.assertEquals;
|
import static junit.framework.Assert.assertEquals;
|
||||||
import static junit.framework.Assert.assertFalse;
|
import static junit.framework.Assert.assertFalse;
|
||||||
|
import static junit.framework.Assert.assertNotNull;
|
||||||
import static junit.framework.Assert.assertNull;
|
import static junit.framework.Assert.assertNull;
|
||||||
import static junit.framework.Assert.assertTrue;
|
import static junit.framework.Assert.assertTrue;
|
||||||
|
|
||||||
@@ -39,7 +40,6 @@ import android.app.Notification;
|
|||||||
import android.app.NotificationChannel;
|
import android.app.NotificationChannel;
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.os.SystemClock;
|
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.service.notification.StatusBarNotification;
|
import android.service.notification.StatusBarNotification;
|
||||||
import android.test.suitebuilder.annotation.SmallTest;
|
import android.test.suitebuilder.annotation.SmallTest;
|
||||||
@@ -50,7 +50,6 @@ import android.util.Xml;
|
|||||||
|
|
||||||
import androidx.test.runner.AndroidJUnit4;
|
import androidx.test.runner.AndroidJUnit4;
|
||||||
|
|
||||||
import com.android.internal.util.FastXmlSerializer;
|
|
||||||
import com.android.server.UiServiceTestCase;
|
import com.android.server.UiServiceTestCase;
|
||||||
import com.android.server.pm.PackageManagerService;
|
import com.android.server.pm.PackageManagerService;
|
||||||
|
|
||||||
@@ -60,9 +59,7 @@ import org.junit.runner.RunWith;
|
|||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
import org.xmlpull.v1.XmlPullParser;
|
|
||||||
import org.xmlpull.v1.XmlPullParserException;
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
import org.xmlpull.v1.XmlSerializer;
|
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.BufferedOutputStream;
|
import java.io.BufferedOutputStream;
|
||||||
@@ -197,18 +194,6 @@ public class SnoozeHelperTest extends UiServiceTestCase {
|
|||||||
systemUser, "pkg", r.getKey()).longValue());
|
systemUser, "pkg", r.getKey()).longValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCleanupContextShouldRemovePersistedRecord() {
|
|
||||||
NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
|
|
||||||
mSnoozeHelper.snooze(r, "context");
|
|
||||||
mSnoozeHelper.cleanupPersistedContext(r.getSbn().getKey());
|
|
||||||
assertNull(mSnoozeHelper.getSnoozeContextForUnpostedNotification(
|
|
||||||
r.getUser().getIdentifier(),
|
|
||||||
r.getSbn().getPackageName(),
|
|
||||||
r.getSbn().getKey()
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadNoneSnoozedNotification() throws XmlPullParserException,
|
public void testReadNoneSnoozedNotification() throws XmlPullParserException,
|
||||||
IOException, InterruptedException {
|
IOException, InterruptedException {
|
||||||
@@ -219,8 +204,9 @@ public class SnoozeHelperTest extends UiServiceTestCase {
|
|||||||
assertEquals("should see a zero value for unsnoozed notification",
|
assertEquals("should see a zero value for unsnoozed notification",
|
||||||
0L,
|
0L,
|
||||||
mSnoozeHelper.getSnoozeTimeForUnpostedNotification(
|
mSnoozeHelper.getSnoozeTimeForUnpostedNotification(
|
||||||
UserHandle.SYSTEM.getIdentifier(),
|
UserHandle.SYSTEM.getIdentifier(), "not_my_package",
|
||||||
"not_my_package", r.getKey()).longValue());
|
getNotificationRecord("not_my_package", 1, "one",
|
||||||
|
UserHandle.SYSTEM).getKey()).longValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -592,7 +578,7 @@ public class SnoozeHelperTest extends UiServiceTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testClearData() {
|
public void testClearData_userPackage() {
|
||||||
// snooze 2 from same package
|
// snooze 2 from same package
|
||||||
NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
|
NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
|
||||||
NotificationRecord r2 = getNotificationRecord("pkg", 2, "two", UserHandle.SYSTEM);
|
NotificationRecord r2 = getNotificationRecord("pkg", 2, "two", UserHandle.SYSTEM);
|
||||||
@@ -615,17 +601,72 @@ public class SnoozeHelperTest extends UiServiceTestCase {
|
|||||||
verify(mAm, times(4)).cancel(any(PendingIntent.class));
|
verify(mAm, times(4)).cancel(any(PendingIntent.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testClearData_user() {
|
||||||
|
// snooze 2 from same package
|
||||||
|
NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
|
||||||
|
NotificationRecord r2 = getNotificationRecord("pkg2", 2, "two", UserHandle.SYSTEM);
|
||||||
|
NotificationRecord r3 = getNotificationRecord("pkg2", 3, "three", UserHandle.SYSTEM);
|
||||||
|
NotificationRecord r4 = getNotificationRecord("pkg", 2, "two", UserHandle.ALL);
|
||||||
|
mSnoozeHelper.snooze(r, 1000);
|
||||||
|
mSnoozeHelper.snooze(r2, 1000);
|
||||||
|
mSnoozeHelper.snooze(r3, "until");
|
||||||
|
mSnoozeHelper.snooze(r4, "until");
|
||||||
|
|
||||||
|
assertTrue(mSnoozeHelper.isSnoozed(
|
||||||
|
UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), r.getKey()));
|
||||||
|
assertTrue(mSnoozeHelper.isSnoozed(
|
||||||
|
UserHandle.USER_SYSTEM, r2.getSbn().getPackageName(), r2.getKey()));
|
||||||
|
assertTrue(mSnoozeHelper.isSnoozed(
|
||||||
|
UserHandle.USER_SYSTEM, r3.getSbn().getPackageName(), r3.getKey()));
|
||||||
|
assertTrue(mSnoozeHelper.isSnoozed(
|
||||||
|
UserHandle.USER_ALL, r4.getSbn().getPackageName(), r4.getKey()));
|
||||||
|
|
||||||
|
// clear data
|
||||||
|
mSnoozeHelper.clearData(UserHandle.USER_SYSTEM);
|
||||||
|
|
||||||
|
// nothing in USER_SYSTEM snoozed; alarms canceled
|
||||||
|
assertFalse(mSnoozeHelper.isSnoozed(
|
||||||
|
UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), r.getKey()));
|
||||||
|
assertFalse(mSnoozeHelper.isSnoozed(
|
||||||
|
UserHandle.USER_SYSTEM, r2.getSbn().getPackageName(), r2.getKey()));
|
||||||
|
assertFalse(mSnoozeHelper.isSnoozed(
|
||||||
|
UserHandle.USER_SYSTEM, r3.getSbn().getPackageName(), r3.getKey()));
|
||||||
|
assertTrue(mSnoozeHelper.isSnoozed(
|
||||||
|
UserHandle.USER_SYSTEM, r4.getSbn().getPackageName(), r4.getKey()));
|
||||||
|
|
||||||
|
assertNull(mSnoozeHelper.getSnoozeContextForUnpostedNotification(
|
||||||
|
r3.getUser().getIdentifier(), r3.getSbn().getPackageName(),
|
||||||
|
r3.getSbn().getKey()));
|
||||||
|
assertNotNull(mSnoozeHelper.getSnoozeContextForUnpostedNotification(
|
||||||
|
r4.getUser().getIdentifier(), r4.getSbn().getPackageName(),
|
||||||
|
r4.getSbn().getKey()));
|
||||||
|
assertEquals(0L, mSnoozeHelper.getSnoozeTimeForUnpostedNotification(
|
||||||
|
r.getUser().getIdentifier(), r.getSbn().getPackageName(),
|
||||||
|
r.getSbn().getKey()).longValue());
|
||||||
|
assertEquals(0L, mSnoozeHelper.getSnoozeTimeForUnpostedNotification(
|
||||||
|
r2.getUser().getIdentifier(), r2.getSbn().getPackageName(),
|
||||||
|
r2.getSbn().getKey()).longValue());
|
||||||
|
|
||||||
|
// 2 for initial timed-snoozes, once each for canceling the USER_SYSTEM snoozes
|
||||||
|
verify(mAm, times(5)).cancel(any(PendingIntent.class));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testClearData_otherRecordsUntouched() {
|
public void testClearData_otherRecordsUntouched() {
|
||||||
// 2 packages, 2 users
|
// 2 packages, 2 users
|
||||||
NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
|
NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
|
||||||
|
NotificationRecord rb = getNotificationRecord("pkg", 1, "oneb", UserHandle.SYSTEM);
|
||||||
NotificationRecord r2 = getNotificationRecord("pkg", 2, "two", UserHandle.ALL);
|
NotificationRecord r2 = getNotificationRecord("pkg", 2, "two", UserHandle.ALL);
|
||||||
NotificationRecord r3 = getNotificationRecord("pkg2", 3, "three", UserHandle.SYSTEM);
|
NotificationRecord r3 = getNotificationRecord("pkg2", 3, "three", UserHandle.SYSTEM);
|
||||||
mSnoozeHelper.snooze(r, 1000);
|
mSnoozeHelper.snooze(r, 1000);
|
||||||
|
mSnoozeHelper.snooze(rb, "until");
|
||||||
mSnoozeHelper.snooze(r2, 1000);
|
mSnoozeHelper.snooze(r2, 1000);
|
||||||
mSnoozeHelper.snooze(r3, 1000);
|
mSnoozeHelper.snooze(r3, 1000);
|
||||||
assertTrue(mSnoozeHelper.isSnoozed(
|
assertTrue(mSnoozeHelper.isSnoozed(
|
||||||
UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), r.getKey()));
|
UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), r.getKey()));
|
||||||
|
assertTrue(mSnoozeHelper.isSnoozed(
|
||||||
|
UserHandle.USER_SYSTEM, rb.getSbn().getPackageName(), rb.getKey()));
|
||||||
assertTrue(mSnoozeHelper.isSnoozed(
|
assertTrue(mSnoozeHelper.isSnoozed(
|
||||||
UserHandle.USER_ALL, r2.getSbn().getPackageName(), r2.getKey()));
|
UserHandle.USER_ALL, r2.getSbn().getPackageName(), r2.getKey()));
|
||||||
assertTrue(mSnoozeHelper.isSnoozed(
|
assertTrue(mSnoozeHelper.isSnoozed(
|
||||||
@@ -636,12 +677,22 @@ public class SnoozeHelperTest extends UiServiceTestCase {
|
|||||||
|
|
||||||
assertFalse(mSnoozeHelper.isSnoozed(
|
assertFalse(mSnoozeHelper.isSnoozed(
|
||||||
UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), r.getKey()));
|
UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), r.getKey()));
|
||||||
|
assertFalse(mSnoozeHelper.isSnoozed(
|
||||||
|
UserHandle.USER_SYSTEM, rb.getSbn().getPackageName(), rb.getKey()));
|
||||||
assertTrue(mSnoozeHelper.isSnoozed(
|
assertTrue(mSnoozeHelper.isSnoozed(
|
||||||
UserHandle.USER_ALL, r2.getSbn().getPackageName(), r2.getKey()));
|
UserHandle.USER_ALL, r2.getSbn().getPackageName(), r2.getKey()));
|
||||||
assertTrue(mSnoozeHelper.isSnoozed(
|
assertTrue(mSnoozeHelper.isSnoozed(
|
||||||
UserHandle.USER_SYSTEM, r3.getSbn().getPackageName(), r3.getKey()));
|
UserHandle.USER_SYSTEM, r3.getSbn().getPackageName(), r3.getKey()));
|
||||||
|
|
||||||
|
assertNull(mSnoozeHelper.getSnoozeContextForUnpostedNotification(
|
||||||
|
rb.getUser().getIdentifier(), rb.getSbn().getPackageName(),
|
||||||
|
rb.getSbn().getKey()));
|
||||||
|
assertEquals(0L, mSnoozeHelper.getSnoozeTimeForUnpostedNotification(
|
||||||
|
r.getUser().getIdentifier(), r.getSbn().getPackageName(),
|
||||||
|
r.getSbn().getKey()).longValue());
|
||||||
|
|
||||||
// once for each initial snooze, once for canceling one snooze
|
// once for each initial snooze, once for canceling one snooze
|
||||||
verify(mAm, times(4)).cancel(any(PendingIntent.class));
|
verify(mAm, times(5)).cancel(any(PendingIntent.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
private NotificationRecord getNotificationRecord(String pkg, int id, String tag,
|
private NotificationRecord getNotificationRecord(String pkg, int id, String tag,
|
||||||
|
|||||||
Reference in New Issue
Block a user