Merge "Ignore flaky test" into rvc-dev
diff --git a/apex/media/framework/java/android/media/MediaParser.java b/apex/media/framework/java/android/media/MediaParser.java
index 566f4cd..b721d87 100644
--- a/apex/media/framework/java/android/media/MediaParser.java
+++ b/apex/media/framework/java/android/media/MediaParser.java
@@ -700,30 +700,34 @@
mDataSource.mInputReader = seekableInputReader;
// TODO: Apply parameters when creating extractor instances.
- if (mExtractorName != null) {
- mExtractor = EXTRACTOR_FACTORIES_BY_NAME.get(mExtractorName).createInstance();
- } else if (mExtractor == null) {
- for (String parserName : mParserNamesPool) {
- Extractor extractor = EXTRACTOR_FACTORIES_BY_NAME.get(parserName).createInstance();
- try {
- if (extractor.sniff(mExtractorInput)) {
- mExtractorName = parserName;
- mExtractor = extractor;
- mExtractor.init(new ExtractorOutputAdapter());
- break;
+ if (mExtractor == null) {
+ if (mExtractorName != null) {
+ mExtractor = EXTRACTOR_FACTORIES_BY_NAME.get(mExtractorName).createInstance();
+ mExtractor.init(new ExtractorOutputAdapter());
+ } else {
+ for (String parserName : mParserNamesPool) {
+ Extractor extractor =
+ EXTRACTOR_FACTORIES_BY_NAME.get(parserName).createInstance();
+ try {
+ if (extractor.sniff(mExtractorInput)) {
+ mExtractorName = parserName;
+ mExtractor = extractor;
+ mExtractor.init(new ExtractorOutputAdapter());
+ break;
+ }
+ } catch (EOFException e) {
+ // Do nothing.
+ } catch (IOException | InterruptedException e) {
+ throw new IllegalStateException(e);
+ } finally {
+ mExtractorInput.resetPeekPosition();
}
- } catch (EOFException e) {
- // Do nothing.
- } catch (IOException | InterruptedException e) {
- throw new IllegalStateException(e);
- } finally {
- mExtractorInput.resetPeekPosition();
}
+ if (mExtractor == null) {
+ throw UnrecognizedInputFormatException.createForExtractors(mParserNamesPool);
+ }
+ return true;
}
- if (mExtractor == null) {
- throw UnrecognizedInputFormatException.createForExtractors(mParserNamesPool);
- }
- return true;
}
if (isPendingSeek()) {
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index b86dc35..e58e7bc 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -380,8 +380,8 @@
BootTimeEventErrorCode boot_time_event_error_code_reported = 242 [(module) = "framework"];
UserspaceRebootReported userspace_reboot_reported = 243 [(module) = "framework"];
NotificationReported notification_reported = 244 [(module) = "framework"];
- NotificationPanelReported notification_panel_reported = 245;
- NotificationChannelModified notification_channel_modified = 246;
+ NotificationPanelReported notification_panel_reported = 245 [(module) = "sysui"];
+ NotificationChannelModified notification_channel_modified = 246 [(module) = "framework"];
IntegrityCheckResultReported integrity_check_result_reported = 247 [(module) = "framework"];
IntegrityRulesPushed integrity_rules_pushed = 248 [(module) = "framework"];
CellBroadcastMessageReported cb_message_reported =
@@ -3637,8 +3637,8 @@
// The notifying app's uid and package.
optional int32 uid = 2 [(is_uid) = true];
optional string package_name = 3;
- // App-assigned notification channel ID or channel-group ID
- optional string channel_id = 4;
+ // Hash of app-assigned notification channel ID or channel-group ID
+ optional int32 channel_id_hash = 4;
// Previous importance setting, if applicable
optional android.stats.sysui.NotificationImportance old_importance = 5;
// New importance setting
diff --git a/graphics/java/android/graphics/fonts/Font.java b/graphics/java/android/graphics/fonts/Font.java
index 853165d..b09082e 100644
--- a/graphics/java/android/graphics/fonts/Font.java
+++ b/graphics/java/android/graphics/fonts/Font.java
@@ -19,6 +19,7 @@
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.content.res.AssetFileDescriptor;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.os.LocaleList;
@@ -219,6 +220,27 @@
Preconditions.checkNotNull(am, "assetManager can not be null");
Preconditions.checkNotNull(path, "path can not be null");
+ // Attempt to open as FD, which should work unless the asset is compressed
+ AssetFileDescriptor assetFD;
+ try {
+ if (isAsset) {
+ assetFD = am.openFd(path);
+ } else if (cookie > 0) {
+ assetFD = am.openNonAssetFd(cookie, path);
+ } else {
+ assetFD = am.openNonAssetFd(path);
+ }
+
+ try (FileInputStream fis = assetFD.createInputStream()) {
+ final FileChannel fc = fis.getChannel();
+ long startOffset = assetFD.getStartOffset();
+ long declaredLength = assetFD.getDeclaredLength();
+ return fc.map(FileChannel.MapMode.READ_ONLY, startOffset, declaredLength);
+ }
+ } catch (IOException e) {
+ // failed to open as FD so now we will attempt to open as an input stream
+ }
+
try (InputStream assetStream = isAsset ? am.open(path, AssetManager.ACCESS_BUFFER)
: am.openNonAsset(cookie, path, AssetManager.ACCESS_BUFFER)) {
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 3afd5dc..7c770f4 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -551,7 +551,7 @@
super.onAnimationEnd(animation);
mScreenshotView.setScaleX(cornerScale);
mScreenshotView.setScaleY(cornerScale);
- mScreenshotView.setX(finalPos.x - height * cornerScale / 2f);
+ mScreenshotView.setX(finalPos.x - width * cornerScale / 2f);
mScreenshotView.setY(finalPos.y - height * cornerScale / 2f);
Rect bounds = new Rect();
mScreenshotView.getBoundsOnScreen(bounds);
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 5b8a6d9..c15360b 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -4060,9 +4060,11 @@
private void readOp(XmlPullParser parser, @NonNull UidState uidState,
@NonNull String pkgName, boolean isPrivileged) throws NumberFormatException,
XmlPullParserException, IOException {
- Op op = new Op(uidState, pkgName,
- Integer.parseInt(parser.getAttributeValue(null, "n")),
- uidState.uid);
+ int opCode = Integer.parseInt(parser.getAttributeValue(null, "n"));
+ if (isIgnoredAppOp(opCode)) {
+ return;
+ }
+ Op op = new Op(uidState, pkgName, opCode, uidState.uid);
final int mode = XmlUtils.readIntAttribute(parser, "m",
AppOpsManager.opToDefaultMode(op.op));
@@ -4096,6 +4098,16 @@
ops.put(op.op, op);
}
+ //TODO(b/149995538): Remove once this has reached all affected devices
+ private static boolean isIgnoredAppOp(int op) {
+ switch (op) {
+ case AppOpsManager.OP_MANAGE_EXTERNAL_STORAGE:
+ return true;
+ default:
+ return false;
+ }
+ }
+
void writeState() {
synchronized (mFile) {
FileOutputStream stream;
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 7a777c1..e6fa610 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -2068,19 +2068,16 @@
@Override
public void onStart() {
- SnoozeHelper snoozeHelper = new SnoozeHelper(getContext(), new SnoozeHelper.Callback() {
- @Override
- public void repost(int userId, NotificationRecord r) {
- try {
- if (DBG) {
- Slog.d(TAG, "Reposting " + r.getKey());
- }
- enqueueNotificationInternal(r.getSbn().getPackageName(), r.getSbn().getOpPkg(),
- r.getSbn().getUid(), r.getSbn().getInitialPid(), r.getSbn().getTag(),
- r.getSbn().getId(), r.getSbn().getNotification(), userId);
- } catch (Exception e) {
- Slog.e(TAG, "Cannot un-snooze notification", e);
+ SnoozeHelper snoozeHelper = new SnoozeHelper(getContext(), (userId, r, muteOnReturn) -> {
+ try {
+ if (DBG) {
+ Slog.d(TAG, "Reposting " + r.getKey());
}
+ enqueueNotificationInternal(r.getSbn().getPackageName(), r.getSbn().getOpPkg(),
+ r.getSbn().getUid(), r.getSbn().getInitialPid(), r.getSbn().getTag(),
+ r.getSbn().getId(), r.getSbn().getNotification(), userId, true);
+ } catch (Exception e) {
+ Slog.e(TAG, "Cannot un-snooze notification", e);
}
}, mUserProfiles);
@@ -3983,7 +3980,7 @@
synchronized (mNotificationLock) {
final ManagedServiceInfo info =
mAssistants.checkServiceTokenLocked(token);
- unsnoozeNotificationInt(key, info);
+ unsnoozeNotificationInt(key, info, false);
}
} finally {
Binder.restoreCallingIdentity(identity);
@@ -4006,7 +4003,7 @@
if (!info.isSystem) {
throw new SecurityException("Not allowed to unsnooze before deadline");
}
- unsnoozeNotificationInt(key, info);
+ unsnoozeNotificationInt(key, info, true);
}
} finally {
Binder.restoreCallingIdentity(identity);
@@ -5525,6 +5522,13 @@
void enqueueNotificationInternal(final String pkg, final String opPkg, final int callingUid,
final int callingPid, final String tag, final int id, final Notification notification,
int incomingUserId) {
+ enqueueNotificationInternal(pkg, opPkg, callingUid, callingPid, tag, id, notification,
+ incomingUserId, false);
+ }
+
+ void enqueueNotificationInternal(final String pkg, final String opPkg, final int callingUid,
+ final int callingPid, final String tag, final int id, final Notification notification,
+ int incomingUserId, boolean postSilently) {
if (DBG) {
Slog.v(TAG, "enqueueNotificationInternal: pkg=" + pkg + " id=" + id
+ " notification=" + notification);
@@ -5605,6 +5609,7 @@
user, null, System.currentTimeMillis());
final NotificationRecord r = new NotificationRecord(getContext(), n, channel);
r.setIsAppImportanceLocked(mPreferencesHelper.getIsAppImportanceLocked(pkg, callingUid));
+ r.setPostSilently(postSilently);
if ((notification.flags & Notification.FLAG_FOREGROUND_SERVICE) != 0) {
final boolean fgServiceShown = channel.isFgServiceShown();
@@ -7040,6 +7045,11 @@
return true;
}
+ // Suppressed because a user manually unsnoozed something (or similar)
+ if (record.shouldPostSilently()) {
+ return true;
+ }
+
// muted by listener
final String disableEffects = disableNotificationEffects(record);
if (disableEffects != null) {
@@ -8054,13 +8064,12 @@
mHandler.post(new SnoozeNotificationRunnable(key, duration, snoozeCriterionId));
}
- void unsnoozeNotificationInt(String key, ManagedServiceInfo listener) {
+ void unsnoozeNotificationInt(String key, ManagedServiceInfo listener, boolean muteOnReturn) {
String listenerName = listener == null ? null : listener.component.toShortString();
if (DBG) {
Slog.d(TAG, String.format("unsnooze event(%s, %s)", key, listenerName));
}
- mSnoozeHelper.cleanupPersistedContext(key);
- mSnoozeHelper.repost(key);
+ mSnoozeHelper.repost(key, muteOnReturn);
handleSavePolicyFile();
}
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index c07107f..3f24b38 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -187,6 +187,7 @@
private boolean mSuggestionsGeneratedByAssistant;
private boolean mEditChoicesBeforeSending;
private boolean mHasSeenSmartReplies;
+ private boolean mPostSilently;
/**
* Whether this notification (and its channels) should be considered user locked. Used in
* conjunction with user sentiment calculation.
@@ -856,6 +857,17 @@
return mHidden;
}
+ /**
+ * Override of all alerting information on the channel and notification. Used when notifications
+ * are reposted in response to direct user action and thus don't need to alert.
+ */
+ public void setPostSilently(boolean postSilently) {
+ mPostSilently = postSilently;
+ }
+
+ public boolean shouldPostSilently() {
+ return mPostSilently;
+ }
public void setSuppressedVisualEffects(int effects) {
mSuppressedVisualEffects = effects;
diff --git a/services/core/java/com/android/server/notification/SnoozeHelper.java b/services/core/java/com/android/server/notification/SnoozeHelper.java
index d60c291..9a9e733 100644
--- a/services/core/java/com/android/server/notification/SnoozeHelper.java
+++ b/services/core/java/com/android/server/notification/SnoozeHelper.java
@@ -106,6 +106,8 @@
private ArrayMap<String, Integer> mUsers = new ArrayMap<>();
private Callback mCallback;
+ private final Object mLock = new Object();
+
public SnoozeHelper(Context context, Callback callback,
ManagedServices.UserProfiles userProfiles) {
mContext = context;
@@ -122,41 +124,52 @@
}
void cleanupPersistedContext(String key){
- int userId = mUsers.get(key);
- String pkg = mPackages.get(key);
- synchronized (mPersistedSnoozedNotificationsWithContext) {
- removeRecord(pkg, key, userId, mPersistedSnoozedNotificationsWithContext);
+ synchronized (mLock) {
+ int userId = mUsers.get(key);
+ String pkg = mPackages.get(key);
+ removeRecordLocked(pkg, key, userId, mPersistedSnoozedNotificationsWithContext);
}
}
- //This function has a side effect of removing the time from the list of persisted notifications.
- //IT IS NOT IDEMPOTENT!
@NonNull
protected Long getSnoozeTimeForUnpostedNotification(int userId, String pkg, String key) {
- Long time;
- synchronized (mPersistedSnoozedNotifications) {
- time = removeRecord(pkg, key, userId, mPersistedSnoozedNotifications);
+ Long time = null;
+ synchronized (mLock) {
+ ArrayMap<String, Long> snoozed =
+ mPersistedSnoozedNotifications.get(getPkgKey(userId, pkg));
+ if (snoozed != null) {
+ time = snoozed.get(key);
+ }
}
if (time == null) {
- return 0L;
+ time = 0L;
}
return time;
}
protected String getSnoozeContextForUnpostedNotification(int userId, String pkg, String key) {
- synchronized (mPersistedSnoozedNotificationsWithContext) {
- return removeRecord(pkg, key, userId, mPersistedSnoozedNotificationsWithContext);
+ synchronized (mLock) {
+ ArrayMap<String, String> snoozed =
+ mPersistedSnoozedNotificationsWithContext.get(getPkgKey(userId, pkg));
+ if (snoozed != null) {
+ return snoozed.get(key);
+ }
}
+ return null;
}
protected boolean isSnoozed(int userId, String pkg, String key) {
- return mSnoozedNotifications.containsKey(getPkgKey(userId, pkg))
- && mSnoozedNotifications.get(getPkgKey(userId, pkg)).containsKey(key);
+ synchronized (mLock) {
+ return mSnoozedNotifications.containsKey(getPkgKey(userId, pkg))
+ && mSnoozedNotifications.get(getPkgKey(userId, pkg)).containsKey(key);
+ }
}
protected Collection<NotificationRecord> getSnoozed(int userId, String pkg) {
- if (mSnoozedNotifications.containsKey(getPkgKey(userId, pkg))) {
- return mSnoozedNotifications.get(getPkgKey(userId, pkg)).values();
+ synchronized (mLock) {
+ if (mSnoozedNotifications.containsKey(getPkgKey(userId, pkg))) {
+ return mSnoozedNotifications.get(getPkgKey(userId, pkg)).values();
+ }
}
return Collections.EMPTY_LIST;
}
@@ -165,14 +178,16 @@
ArrayList<NotificationRecord> getNotifications(String pkg,
String groupKey, Integer userId) {
ArrayList<NotificationRecord> records = new ArrayList<>();
- ArrayMap<String, NotificationRecord> allRecords =
- mSnoozedNotifications.get(getPkgKey(userId, pkg));
- if (allRecords != null) {
- for (int i = 0; i < allRecords.size(); i++) {
- NotificationRecord r = allRecords.valueAt(i);
- String currentGroupKey = r.getSbn().getGroup();
- if (Objects.equals(currentGroupKey, groupKey)) {
- records.add(r);
+ synchronized (mLock) {
+ ArrayMap<String, NotificationRecord> allRecords =
+ mSnoozedNotifications.get(getPkgKey(userId, pkg));
+ if (allRecords != null) {
+ for (int i = 0; i < allRecords.size(); i++) {
+ NotificationRecord r = allRecords.valueAt(i);
+ String currentGroupKey = r.getSbn().getGroup();
+ if (Objects.equals(currentGroupKey, groupKey)) {
+ records.add(r);
+ }
}
}
}
@@ -180,30 +195,34 @@
}
protected NotificationRecord getNotification(String key) {
- if (!mUsers.containsKey(key) || !mPackages.containsKey(key)) {
- Slog.w(TAG, "Snoozed data sets no longer agree for " + key);
- return null;
+ synchronized (mLock) {
+ if (!mUsers.containsKey(key) || !mPackages.containsKey(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);
}
- 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() {
- // caller filters records based on the current user profiles and listener access, so just
- // return everything
- List<NotificationRecord> snoozed= new ArrayList<>();
- for (String userPkgKey : mSnoozedNotifications.keySet()) {
- ArrayMap<String, NotificationRecord> snoozedRecords =
- mSnoozedNotifications.get(userPkgKey);
- snoozed.addAll(snoozedRecords.values());
+ synchronized (mLock) {
+ // caller filters records based on the current user profiles and listener access, so just
+ // return everything
+ List<NotificationRecord> snoozed = new ArrayList<>();
+ for (String userPkgKey : mSnoozedNotifications.keySet()) {
+ ArrayMap<String, NotificationRecord> snoozedRecords =
+ mSnoozedNotifications.get(userPkgKey);
+ snoozed.addAll(snoozedRecords.values());
+ }
+ return snoozed;
}
- return snoozed;
}
/**
@@ -216,9 +235,9 @@
snooze(record);
scheduleRepost(pkg, key, userId, duration);
- Long activateAt = SystemClock.elapsedRealtime() + duration;
- synchronized (mPersistedSnoozedNotifications) {
- storeRecord(pkg, key, userId, mPersistedSnoozedNotifications, activateAt);
+ Long activateAt = System.currentTimeMillis() + duration;
+ synchronized (mLock) {
+ storeRecordLocked(pkg, key, userId, mPersistedSnoozedNotifications, activateAt);
}
}
@@ -228,8 +247,8 @@
protected void snooze(NotificationRecord record, String contextId) {
int userId = record.getUser().getIdentifier();
if (contextId != null) {
- synchronized (mPersistedSnoozedNotificationsWithContext) {
- storeRecord(record.getSbn().getPackageName(), record.getKey(),
+ synchronized (mLock) {
+ storeRecordLocked(record.getSbn().getPackageName(), record.getKey(),
userId, mPersistedSnoozedNotificationsWithContext, contextId);
}
}
@@ -241,25 +260,26 @@
if (DEBUG) {
Slog.d(TAG, "Snoozing " + record.getKey());
}
- storeRecord(record.getSbn().getPackageName(), record.getKey(),
- userId, mSnoozedNotifications, record);
+ synchronized (mLock) {
+ storeRecordLocked(record.getSbn().getPackageName(), record.getKey(),
+ userId, mSnoozedNotifications, record);
+ }
}
- private <T> void storeRecord(String pkg, String key, Integer userId,
+ 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);
-
- mPackages.put(key, pkg);
- mUsers.put(key, userId);
}
- private <T> T removeRecord(String pkg, String key, Integer userId,
+ 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));
@@ -274,15 +294,17 @@
}
protected boolean cancel(int userId, String pkg, String tag, int id) {
- ArrayMap<String, NotificationRecord> recordsForPkg =
- mSnoozedNotifications.get(getPkgKey(userId, pkg));
- if (recordsForPkg != null) {
- final Set<Map.Entry<String, NotificationRecord>> records = recordsForPkg.entrySet();
- for (Map.Entry<String, NotificationRecord> record : records) {
- final StatusBarNotification sbn = record.getValue().getSbn();
- if (Objects.equals(sbn.getTag(), tag) && sbn.getId() == id) {
- record.getValue().isCanceled = true;
- return true;
+ synchronized (mLock) {
+ ArrayMap<String, NotificationRecord> recordsForPkg =
+ mSnoozedNotifications.get(getPkgKey(userId, pkg));
+ if (recordsForPkg != null) {
+ final Set<Map.Entry<String, NotificationRecord>> records = recordsForPkg.entrySet();
+ for (Map.Entry<String, NotificationRecord> record : records) {
+ final StatusBarNotification sbn = record.getValue().getSbn();
+ if (Objects.equals(sbn.getTag(), tag) && sbn.getId() == id) {
+ record.getValue().isCanceled = true;
+ return true;
+ }
}
}
}
@@ -290,125 +312,149 @@
}
protected void cancel(int userId, boolean includeCurrentProfiles) {
- if (mSnoozedNotifications.size() == 0) {
- return;
- }
- IntArray userIds = new IntArray();
- userIds.add(userId);
- if (includeCurrentProfiles) {
- userIds = mUserProfiles.getCurrentProfileIds();
- }
- for (ArrayMap<String, NotificationRecord> snoozedRecords : mSnoozedNotifications.values()) {
- for (NotificationRecord r : snoozedRecords.values()) {
- if (userIds.binarySearch(r.getUserId()) >= 0) {
- r.isCanceled = true;
+ synchronized (mLock) {
+ if (mSnoozedNotifications.size() == 0) {
+ return;
+ }
+ IntArray userIds = new IntArray();
+ userIds.add(userId);
+ if (includeCurrentProfiles) {
+ userIds = mUserProfiles.getCurrentProfileIds();
+ }
+ for (ArrayMap<String, NotificationRecord> snoozedRecords : mSnoozedNotifications.values()) {
+ for (NotificationRecord r : snoozedRecords.values()) {
+ if (userIds.binarySearch(r.getUserId()) >= 0) {
+ r.isCanceled = true;
+ }
}
}
}
}
protected boolean cancel(int userId, String pkg) {
- ArrayMap<String, NotificationRecord> records =
- mSnoozedNotifications.get(getPkgKey(userId, pkg));
- if (records == null) {
- return false;
+ synchronized (mLock) {
+ ArrayMap<String, NotificationRecord> records =
+ mSnoozedNotifications.get(getPkgKey(userId, pkg));
+ if (records == null) {
+ return false;
+ }
+ int N = records.size();
+ for (int i = 0; i < N; i++) {
+ records.valueAt(i).isCanceled = true;
+ }
+ return true;
}
- int N = records.size();
- for (int i = 0; i < N; i++) {
- records.valueAt(i).isCanceled = true;
- }
- return true;
}
/**
* Updates the notification record so the most up to date information is shown on re-post.
*/
protected void update(int userId, NotificationRecord record) {
- ArrayMap<String, NotificationRecord> records =
- mSnoozedNotifications.get(getPkgKey(userId, record.getSbn().getPackageName()));
- if (records == null) {
- return;
- }
- records.put(record.getKey(), record);
- }
-
- protected void repost(String key) {
- Integer userId = mUsers.get(key);
- if (userId != null) {
- repost(key, userId);
+ synchronized (mLock) {
+ ArrayMap<String, NotificationRecord> records =
+ mSnoozedNotifications.get(getPkgKey(userId, record.getSbn().getPackageName()));
+ if (records == null) {
+ return;
+ }
+ records.put(record.getKey(), record);
}
}
- protected void repost(String key, int userId) {
- final String pkg = mPackages.remove(key);
- ArrayMap<String, NotificationRecord> records =
- mSnoozedNotifications.get(getPkgKey(userId, pkg));
- if (records == null) {
- return;
+ protected void repost(String key, boolean muteOnReturn) {
+ synchronized (mLock) {
+ Integer userId = mUsers.get(key);
+ if (userId != null) {
+ repost(key, userId, muteOnReturn);
+ }
}
- final NotificationRecord record = records.remove(key);
- mPackages.remove(key);
- mUsers.remove(key);
+ }
+
+ protected void repost(String key, int userId, boolean muteOnReturn) {
+ NotificationRecord record;
+ synchronized (mLock) {
+ final String pkg = mPackages.remove(key);
+ mUsers.remove(key);
+ removeRecordLocked(pkg, key, userId, mPersistedSnoozedNotifications);
+ 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) {
- final PendingIntent pi = createPendingIntent(pkg, record.getKey(), userId);
+ final PendingIntent pi = createPendingIntent(
+ record.getSbn().getPackageName(), record.getKey(), userId);
mAm.cancel(pi);
MetricsLogger.action(record.getLogMaker()
.setCategory(MetricsProto.MetricsEvent.NOTIFICATION_SNOOZED)
.setType(MetricsProto.MetricsEvent.TYPE_OPEN));
- mCallback.repost(userId, record);
+ mCallback.repost(userId, record, muteOnReturn);
}
}
protected void repostGroupSummary(String pkg, int userId, String groupKey) {
- ArrayMap<String, NotificationRecord> recordsByKey
- = mSnoozedNotifications.get(getPkgKey(userId, pkg));
- if (recordsByKey == null) {
- return;
- }
-
- String groupSummaryKey = null;
- int N = recordsByKey.size();
- for (int i = 0; i < N; i++) {
- final NotificationRecord potentialGroupSummary = recordsByKey.valueAt(i);
- if (potentialGroupSummary.getSbn().isGroup()
- && potentialGroupSummary.getNotification().isGroupSummary()
- && groupKey.equals(potentialGroupSummary.getGroupKey())) {
- groupSummaryKey = potentialGroupSummary.getKey();
- break;
+ synchronized (mLock) {
+ ArrayMap<String, NotificationRecord> recordsByKey
+ = mSnoozedNotifications.get(getPkgKey(userId, pkg));
+ if (recordsByKey == null) {
+ return;
}
- }
- if (groupSummaryKey != null) {
- NotificationRecord record = recordsByKey.remove(groupSummaryKey);
- mPackages.remove(groupSummaryKey);
- mUsers.remove(groupSummaryKey);
+ String groupSummaryKey = null;
+ int N = recordsByKey.size();
+ for (int i = 0; i < N; i++) {
+ final NotificationRecord potentialGroupSummary = recordsByKey.valueAt(i);
+ if (potentialGroupSummary.getSbn().isGroup()
+ && potentialGroupSummary.getNotification().isGroupSummary()
+ && groupKey.equals(potentialGroupSummary.getGroupKey())) {
+ groupSummaryKey = potentialGroupSummary.getKey();
+ break;
+ }
+ }
- if (record != null && !record.isCanceled) {
- MetricsLogger.action(record.getLogMaker()
- .setCategory(MetricsProto.MetricsEvent.NOTIFICATION_SNOOZED)
- .setType(MetricsProto.MetricsEvent.TYPE_OPEN));
- mCallback.repost(userId, record);
+ if (groupSummaryKey != null) {
+ NotificationRecord record = recordsByKey.remove(groupSummaryKey);
+ mPackages.remove(groupSummaryKey);
+ mUsers.remove(groupSummaryKey);
+
+ if (record != null && !record.isCanceled) {
+ Runnable runnable = () -> {
+ MetricsLogger.action(record.getLogMaker()
+ .setCategory(MetricsProto.MetricsEvent.NOTIFICATION_SNOOZED)
+ .setType(MetricsProto.MetricsEvent.TYPE_OPEN));
+ mCallback.repost(userId, record, false);
+ };
+ runnable.run();
+ }
}
}
}
protected void clearData(int userId, String pkg) {
- ArrayMap<String, NotificationRecord> records =
- mSnoozedNotifications.get(getPkgKey(userId, pkg));
- if (records == null) {
- return;
- }
- for (int i = records.size() - 1; i >= 0; i--) {
- final NotificationRecord r = records.removeAt(i);
- if (r != null) {
- mPackages.remove(r.getKey());
- mUsers.remove(r.getKey());
- final PendingIntent pi = createPendingIntent(pkg, r.getKey(), userId);
- mAm.cancel(pi);
- MetricsLogger.action(r.getLogMaker()
- .setCategory(MetricsProto.MetricsEvent.NOTIFICATION_SNOOZED)
- .setType(MetricsProto.MetricsEvent.TYPE_DISMISS));
+ synchronized (mLock) {
+ ArrayMap<String, NotificationRecord> records =
+ mSnoozedNotifications.get(getPkgKey(userId, pkg));
+ if (records == null) {
+ return;
+ }
+ for (int i = records.size() - 1; i >= 0; i--) {
+ final NotificationRecord r = records.removeAt(i);
+ if (r != null) {
+ mPackages.remove(r.getKey());
+ mUsers.remove(r.getKey());
+ Runnable runnable = () -> {
+ final PendingIntent pi = createPendingIntent(pkg, r.getKey(), userId);
+ mAm.cancel(pi);
+ MetricsLogger.action(r.getLogMaker()
+ .setCategory(MetricsProto.MetricsEvent.NOTIFICATION_SNOOZED)
+ .setType(MetricsProto.MetricsEvent.TYPE_DISMISS));
+ };
+ runnable.run();
+ }
}
}
}
@@ -425,93 +471,102 @@
}
public void scheduleRepostsForPersistedNotifications(long currentTime) {
- for (ArrayMap<String, Long> snoozed : mPersistedSnoozedNotifications.values()) {
- for (int i = 0; i < snoozed.size(); i++) {
- String key = snoozed.keyAt(i);
- Long time = snoozed.valueAt(i);
- String pkg = mPackages.get(key);
- 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);
+ synchronized (mLock) {
+ for (ArrayMap<String, Long> snoozed : mPersistedSnoozedNotifications.values()) {
+ for (int i = 0; i < snoozed.size(); i++) {
+ String key = snoozed.keyAt(i);
+ Long time = snoozed.valueAt(i);
+ String pkg = mPackages.get(key);
+ 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) {
- scheduleRepostAtTime(pkg, key, userId, SystemClock.elapsedRealtime() + duration);
+ scheduleRepostAtTime(pkg, key, userId, System.currentTimeMillis() + duration);
}
private void scheduleRepostAtTime(String pkg, String key, int userId, long time) {
- long identity = Binder.clearCallingIdentity();
- try {
- final PendingIntent pi = createPendingIntent(pkg, key, userId);
- mAm.cancel(pi);
- if (DEBUG) Slog.d(TAG, "Scheduling evaluate for " + new Date(time));
- mAm.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP, time, pi);
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
+ Runnable runnable = () -> {
+ long identity = Binder.clearCallingIdentity();
+ try {
+ final PendingIntent pi = createPendingIntent(pkg, key, userId);
+ mAm.cancel(pi);
+ if (DEBUG) Slog.d(TAG, "Scheduling evaluate for " + new Date(time));
+ mAm.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, time, pi);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ };
+ runnable.run();
}
public void dump(PrintWriter pw, NotificationManagerService.DumpFilter filter) {
- pw.println("\n Snoozed notifications:");
- for (String userPkgKey : mSnoozedNotifications.keySet()) {
- pw.print(INDENT);
- pw.println("key: " + userPkgKey);
- ArrayMap<String, NotificationRecord> snoozedRecords =
- mSnoozedNotifications.get(userPkgKey);
- Set<String> snoozedKeys = snoozedRecords.keySet();
- for (String key : snoozedKeys) {
+ synchronized (mLock) {
+ pw.println("\n Snoozed notifications:");
+ for (String userPkgKey : mSnoozedNotifications.keySet()) {
pw.print(INDENT);
- pw.print(INDENT);
- pw.print(INDENT);
- pw.println(key);
+ pw.println("key: " + userPkgKey);
+ 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");
- for (String userPkgKey : mPersistedSnoozedNotifications.keySet()) {
- pw.print(INDENT);
- pw.println("key: " + userPkgKey);
- ArrayMap<String, Long> snoozedRecords =
- mPersistedSnoozedNotifications.get(userPkgKey);
- if (snoozedRecords == null) {
- continue;
- }
- Set<String> snoozedKeys = snoozedRecords.keySet();
- for (String key : snoozedKeys) {
+ pw.println("\n Pending snoozed notifications");
+ for (String userPkgKey : mPersistedSnoozedNotifications.keySet()) {
pw.print(INDENT);
- pw.print(INDENT);
- pw.print(INDENT);
- pw.print(key);
- pw.print(INDENT);
- pw.println(snoozedRecords.get(key));
+ pw.println("key: " + userPkgKey);
+ 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));
+ }
}
}
}
protected void writeXml(XmlSerializer out) throws IOException {
- final long currentTime = System.currentTimeMillis();
- out.startTag(null, XML_TAG_NAME);
- writeXml(out, mPersistedSnoozedNotifications, XML_SNOOZED_NOTIFICATION,
- value -> {
- if (value < currentTime) {
- return;
- }
- out.attribute(null, XML_SNOOZED_NOTIFICATION_TIME,
- value.toString());
- });
- writeXml(out, mPersistedSnoozedNotificationsWithContext, XML_SNOOZED_NOTIFICATION_CONTEXT,
- value -> {
- out.attribute(null, XML_SNOOZED_NOTIFICATION_CONTEXT_ID,
- value);
- });
- out.endTag(null, XML_TAG_NAME);
+ synchronized (mLock) {
+ final long currentTime = System.currentTimeMillis();
+ out.startTag(null, XML_TAG_NAME);
+ writeXml(out, mPersistedSnoozedNotifications, XML_SNOOZED_NOTIFICATION,
+ value -> {
+ if (value < currentTime) {
+ return;
+ }
+ out.attribute(null, XML_SNOOZED_NOTIFICATION_TIME,
+ value.toString());
+ });
+ writeXml(out, mPersistedSnoozedNotificationsWithContext,
+ XML_SNOOZED_NOTIFICATION_CONTEXT,
+ value -> {
+ out.attribute(null, XML_SNOOZED_NOTIFICATION_CONTEXT_ID,
+ value);
+ });
+ out.endTag(null, XML_TAG_NAME);
+ }
}
private interface Inserter<T> {
@@ -522,32 +577,35 @@
ArrayMap<String, ArrayMap<String, T>> targets, String tag,
Inserter<T> attributeInserter)
throws IOException {
- synchronized (targets) {
- final int M = targets.size();
- for (int i = 0; i < M; i++) {
- // T is a String (snoozed until context) or Long (snoozed until time)
- ArrayMap<String, T> keyToValue = targets.valueAt(i);
- 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);
+ final int M = targets.size();
+ for (int i = 0; i < M; i++) {
+ // T is a String (snoozed until context) or Long (snoozed until time)
+ ArrayMap<String, T> keyToValue = targets.valueAt(i);
+ 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);
- out.startTag(null, tag);
-
- attributeInserter.insert(value);
-
- out.attribute(null, XML_SNOOZED_NOTIFICATION_VERSION_LABEL,
- XML_SNOOZED_NOTIFICATION_VERSION);
- out.attribute(null, XML_SNOOZED_NOTIFICATION_KEY, key);
-
-
- out.attribute(null, XML_SNOOZED_NOTIFICATION_PKG, pkg);
- out.attribute(null, XML_SNOOZED_NOTIFICATION_USER_ID,
- String.valueOf(userId));
-
- out.endTag(null, tag);
+ if (pkg == null || userId == null) {
+ Slog.w(TAG, "pkg " + pkg + " or user " + userId + " missing for " + key);
+ continue;
}
+
+ out.startTag(null, tag);
+
+ attributeInserter.insert(value);
+
+ out.attribute(null, XML_SNOOZED_NOTIFICATION_VERSION_LABEL,
+ XML_SNOOZED_NOTIFICATION_VERSION);
+ out.attribute(null, XML_SNOOZED_NOTIFICATION_KEY, key);
+
+
+ out.attribute(null, XML_SNOOZED_NOTIFICATION_PKG, pkg);
+ out.attribute(null, XML_SNOOZED_NOTIFICATION_USER_ID,
+ String.valueOf(userId));
+
+ out.endTag(null, tag);
}
}
}
@@ -575,16 +633,18 @@
final Long time = XmlUtils.readLongAttribute(
parser, XML_SNOOZED_NOTIFICATION_TIME, 0);
if (time > currentTime) { //only read new stuff
- synchronized (mPersistedSnoozedNotifications) {
- storeRecord(pkg, key, userId, mPersistedSnoozedNotifications, time);
+ synchronized (mLock) {
+ storeRecordLocked(
+ pkg, key, userId, mPersistedSnoozedNotifications, time);
}
}
}
if (tag.equals(XML_SNOOZED_NOTIFICATION_CONTEXT)) {
final String creationId = parser.getAttributeValue(
null, XML_SNOOZED_NOTIFICATION_CONTEXT_ID);
- synchronized (mPersistedSnoozedNotificationsWithContext) {
- storeRecord(pkg, key, userId, mPersistedSnoozedNotificationsWithContext,
+ synchronized (mLock) {
+ storeRecordLocked(
+ pkg, key, userId, mPersistedSnoozedNotificationsWithContext,
creationId);
}
}
@@ -601,7 +661,7 @@
}
protected interface Callback {
- void repost(int userId, NotificationRecord r);
+ void repost(int userId, NotificationRecord r, boolean muteOnReturn);
}
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@@ -612,7 +672,7 @@
}
if (REPOST_ACTION.equals(intent.getAction())) {
repost(intent.getStringExtra(EXTRA_KEY), intent.getIntExtra(EXTRA_USER_ID,
- UserHandle.USER_SYSTEM));
+ UserHandle.USER_SYSTEM), false);
}
}
};
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 440b779..36c0659 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -4674,22 +4674,24 @@
return getUserDataUnchecked(userHandle).mAdminList;
}
ArrayList<ActiveAdmin> admins = new ArrayList<>();
- for (UserInfo userInfo : mUserManager.getProfiles(userHandle)) {
- DevicePolicyData policy = getUserDataUnchecked(userInfo.id);
- if (userInfo.id == userHandle) {
- admins.addAll(policy.mAdminList);
- } else if (userInfo.isManagedProfile()) {
- // For managed profiles, policies set on the parent profile will be included
- for (int i = 0; i < policy.mAdminList.size(); i++) {
- ActiveAdmin admin = policy.mAdminList.get(i);
- if (admin.hasParentActiveAdmin()) {
- admins.add(admin.getParentActiveAdmin());
+ mInjector.binderWithCleanCallingIdentity(() -> {
+ for (UserInfo userInfo : mUserManager.getProfiles(userHandle)) {
+ DevicePolicyData policy = getUserDataUnchecked(userInfo.id);
+ if (userInfo.id == userHandle) {
+ admins.addAll(policy.mAdminList);
+ } else if (userInfo.isManagedProfile()) {
+ // For managed profiles, policies set on the parent profile will be included
+ for (int i = 0; i < policy.mAdminList.size(); i++) {
+ ActiveAdmin admin = policy.mAdminList.get(i);
+ if (admin.hasParentActiveAdmin()) {
+ admins.add(admin.getParentActiveAdmin());
+ }
}
+ } else {
+ Slog.w(LOG_TAG, "Unknown user type: " + userInfo);
}
- } else {
- Slog.w(LOG_TAG, "Unknown user type: " + userInfo);
}
- }
+ });
return admins;
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
index f029bc8..afd10dd 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
@@ -846,6 +846,18 @@
}
@Test
+ public void testPostSilently() throws Exception {
+ NotificationRecord r = getBuzzyNotification();
+ r.setPostSilently(true);
+
+ mService.buzzBeepBlinkLocked(r);
+
+ verifyNeverBeep();
+ assertFalse(r.isInterruptive());
+ assertEquals(-1, r.getLastAudiblyAlertedMs());
+ }
+
+ @Test
public void testGroupAlertSummarySilenceChild() throws Exception {
NotificationRecord child = getBeepyNotificationRecord("a", GROUP_ALERT_SUMMARY);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java
index 816e8e5..3deeea2 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java
@@ -22,6 +22,7 @@
import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
@@ -249,7 +250,7 @@
ArgumentCaptor<Long> captor = ArgumentCaptor.forClass(Long.class);
verify(mAm, times(1)).setExactAndAllowWhileIdle(
anyInt(), captor.capture(), any(PendingIntent.class));
- long actualSnoozedUntilDuration = captor.getValue() - SystemClock.elapsedRealtime();
+ long actualSnoozedUntilDuration = captor.getValue() - System.currentTimeMillis();
assertTrue(Math.abs(actualSnoozedUntilDuration - 1000) < 250);
assertTrue(mSnoozeHelper.isSnoozed(
UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), r.getKey()));
@@ -363,8 +364,8 @@
mSnoozeHelper.cancel(UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), "one", 1);
- mSnoozeHelper.repost(r.getKey(), UserHandle.USER_SYSTEM);
- verify(mCallback, never()).repost(UserHandle.USER_SYSTEM, r);
+ mSnoozeHelper.repost(r.getKey(), UserHandle.USER_SYSTEM, false);
+ verify(mCallback, never()).repost(UserHandle.USER_SYSTEM, r, false);
}
@Test
@@ -374,8 +375,8 @@
NotificationRecord r2 = getNotificationRecord("pkg", 2, "one", UserHandle.ALL);
mSnoozeHelper.snooze(r2, 1000);
reset(mAm);
- mSnoozeHelper.repost(r.getKey(), UserHandle.USER_SYSTEM);
- verify(mCallback, times(1)).repost(UserHandle.USER_SYSTEM, r);
+ mSnoozeHelper.repost(r.getKey(), UserHandle.USER_SYSTEM, false);
+ verify(mCallback, times(1)).repost(UserHandle.USER_SYSTEM, r, false);
ArgumentCaptor<PendingIntent> captor = ArgumentCaptor.forClass(PendingIntent.class);
verify(mAm).cancel(captor.capture());
assertEquals(r.getKey(), captor.getValue().getIntent().getStringExtra(EXTRA_KEY));
@@ -388,8 +389,8 @@
NotificationRecord r2 = getNotificationRecord("pkg", 2, "one", UserHandle.ALL);
mSnoozeHelper.snooze(r2, 1000);
reset(mAm);
- mSnoozeHelper.repost(r.getKey());
- verify(mCallback, times(1)).repost(UserHandle.USER_SYSTEM, r);
+ mSnoozeHelper.repost(r.getKey(), false);
+ verify(mCallback, times(1)).repost(UserHandle.USER_SYSTEM, r, false);
verify(mAm).cancel(any(PendingIntent.class));
}
@@ -400,10 +401,10 @@
r.getNotification().category = "NEW CATEGORY";
mSnoozeHelper.update(UserHandle.USER_SYSTEM, r);
- verify(mCallback, never()).repost(anyInt(), any(NotificationRecord.class));
+ verify(mCallback, never()).repost(anyInt(), any(NotificationRecord.class), anyBoolean());
- mSnoozeHelper.repost(r.getKey(), UserHandle.USER_SYSTEM);
- verify(mCallback, times(1)).repost(UserHandle.USER_SYSTEM, r);
+ mSnoozeHelper.repost(r.getKey(), UserHandle.USER_SYSTEM, false);
+ verify(mCallback, times(1)).repost(UserHandle.USER_SYSTEM, r, false);
}
@Test
@@ -420,13 +421,23 @@
mSnoozeHelper.update(UserHandle.USER_SYSTEM, r);
// verify callback is called when repost (snooze is expired)
- verify(mCallback, never()).repost(anyInt(), any(NotificationRecord.class));
- mSnoozeHelper.repost(r.getKey(), UserHandle.USER_SYSTEM);
- verify(mCallback, times(1)).repost(UserHandle.USER_SYSTEM, r);
+ verify(mCallback, never()).repost(anyInt(), any(NotificationRecord.class), anyBoolean());
+ mSnoozeHelper.repost(r.getKey(), UserHandle.USER_SYSTEM, false);
+ verify(mCallback, times(1)).repost(UserHandle.USER_SYSTEM, r, false);
assertFalse(r.isCanceled);
}
@Test
+ public void testReport_passesFlag() throws Exception {
+ // snooze a notification
+ NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
+ mSnoozeHelper.snooze(r , 1000);
+
+ mSnoozeHelper.repost(r.getKey(), UserHandle.USER_SYSTEM, true);
+ verify(mCallback, times(1)).repost(UserHandle.USER_SYSTEM, r, true);
+ }
+
+ @Test
public void testGetSnoozedBy() throws Exception {
NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
NotificationRecord r2 = getNotificationRecord("pkg", 2, "two", UserHandle.SYSTEM);
@@ -523,7 +534,7 @@
mSnoozeHelper.snooze(r2, 1000);
mSnoozeHelper.repostGroupSummary("pkg", UserHandle.USER_SYSTEM, "group1");
- verify(mCallback, never()).repost(UserHandle.USER_SYSTEM, r);
+ verify(mCallback, never()).repost(eq(UserHandle.USER_SYSTEM), eq(r), anyBoolean());
}
@Test
@@ -542,8 +553,8 @@
mSnoozeHelper.repostGroupSummary("pkg", UserHandle.USER_SYSTEM, r.getGroupKey());
- verify(mCallback, times(1)).repost(UserHandle.USER_SYSTEM, r);
- verify(mCallback, never()).repost(UserHandle.USER_SYSTEM, r2);
+ verify(mCallback, times(1)).repost(UserHandle.USER_SYSTEM, r, false);
+ verify(mCallback, never()).repost(UserHandle.USER_SYSTEM, r2, false);
assertEquals(1, mSnoozeHelper.getSnoozed().size());
assertEquals(1, mSnoozeHelper.getSnoozed(UserHandle.USER_SYSTEM, "pkg").size());