summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Yuri Lin <yurilin@google.com> 2023-04-12 14:02:52 -0400
committer Yuri Lin <yurilin@google.com> 2023-05-16 13:54:46 -0400
commit7e1156b658014e3f52ccdacb93ebfd193e6340fd (patch)
treef01128d5be29da85b40cfefe45acb8dd4e5c7919
parent7fbed032f66d24e23f1bbb06c3e5094a73a06373 (diff)
Add logging for zen mode events.
Gated on the LOG_DND_STATE_EVENTS flag. This change adds a ZenModeEventLogger that logs atoms on zen mode state changes, policy changes, and changes in the number of active automatic rules. Additionally adjusts some methods in ZenModeHelper to pass the calling UID through (not gated by flag), which is only used when logging. Bug: 259261349 Test: ZenModeHelperTest, PreferencesHelperTest, NotificationManagerServiceTest, AudioManagerTest (cts), NotificationManagerTest (cts), CtsLegacyNotification27TestCases, manual via statsd_testdrive Change-Id: I4ed2d664b501b3cf281aa70a90a1d4fb8cebdf2e
-rw-r--r--core/java/android/service/notification/ZenModeDiff.java138
-rw-r--r--core/proto/android/service/notification.proto8
-rwxr-xr-xservices/core/java/com/android/server/notification/NotificationManagerService.java63
-rw-r--r--services/core/java/com/android/server/notification/PreferencesHelper.java42
-rw-r--r--services/core/java/com/android/server/notification/RankingConfig.java12
-rw-r--r--services/core/java/com/android/server/notification/ZenModeConditions.java10
-rw-r--r--services/core/java/com/android/server/notification/ZenModeEventLogger.java611
-rw-r--r--services/core/java/com/android/server/notification/ZenModeHelper.java143
-rwxr-xr-xservices/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java58
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java924
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/TestableNotificationManagerService.java8
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/ZenModeEventLoggerFake.java132
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java632
13 files changed, 2253 insertions, 528 deletions
diff --git a/core/java/android/service/notification/ZenModeDiff.java b/core/java/android/service/notification/ZenModeDiff.java
index c7b89eb284b6..a4f129ec247e 100644
--- a/core/java/android/service/notification/ZenModeDiff.java
+++ b/core/java/android/service/notification/ZenModeDiff.java
@@ -205,12 +205,24 @@ public class ZenModeDiff {
private final ArrayMap<String, RuleDiff> mAutomaticRulesDiff = new ArrayMap<>();
private RuleDiff mManualRuleDiff;
- // Helpers for string generation
- private static final String ALLOW_CALLS_FROM_FIELD = "allowCallsFrom";
- private static final String ALLOW_MESSAGES_FROM_FIELD = "allowMessagesFrom";
- private static final String ALLOW_CONVERSATIONS_FROM_FIELD = "allowConversationsFrom";
+ // Field name constants
+ public static final String FIELD_USER = "user";
+ public static final String FIELD_ALLOW_ALARMS = "allowAlarms";
+ public static final String FIELD_ALLOW_MEDIA = "allowMedia";
+ public static final String FIELD_ALLOW_SYSTEM = "allowSystem";
+ public static final String FIELD_ALLOW_CALLS = "allowCalls";
+ public static final String FIELD_ALLOW_REMINDERS = "allowReminders";
+ public static final String FIELD_ALLOW_EVENTS = "allowEvents";
+ public static final String FIELD_ALLOW_REPEAT_CALLERS = "allowRepeatCallers";
+ public static final String FIELD_ALLOW_MESSAGES = "allowMessages";
+ public static final String FIELD_ALLOW_CONVERSATIONS = "allowConversations";
+ public static final String FIELD_ALLOW_CALLS_FROM = "allowCallsFrom";
+ public static final String FIELD_ALLOW_MESSAGES_FROM = "allowMessagesFrom";
+ public static final String FIELD_ALLOW_CONVERSATIONS_FROM = "allowConversationsFrom";
+ public static final String FIELD_SUPPRESSED_VISUAL_EFFECTS = "suppressedVisualEffects";
+ public static final String FIELD_ARE_CHANNELS_BYPASSING_DND = "areChannelsBypassingDnd";
private static final Set<String> PEOPLE_TYPE_FIELDS =
- Set.of(ALLOW_CALLS_FROM_FIELD, ALLOW_MESSAGES_FROM_FIELD);
+ Set.of(FIELD_ALLOW_CALLS_FROM, FIELD_ALLOW_MESSAGES_FROM);
/**
* Create a diff that contains diffs between the "from" and "to" ZenModeConfigs.
@@ -232,57 +244,57 @@ public class ZenModeDiff {
// Now we compare all the fields, knowing there's a diff and that neither is null
if (from.user != to.user) {
- addField("user", new FieldDiff<>(from.user, to.user));
+ addField(FIELD_USER, new FieldDiff<>(from.user, to.user));
}
if (from.allowAlarms != to.allowAlarms) {
- addField("allowAlarms", new FieldDiff<>(from.allowAlarms, to.allowAlarms));
+ addField(FIELD_ALLOW_ALARMS, new FieldDiff<>(from.allowAlarms, to.allowAlarms));
}
if (from.allowMedia != to.allowMedia) {
- addField("allowMedia", new FieldDiff<>(from.allowMedia, to.allowMedia));
+ addField(FIELD_ALLOW_MEDIA, new FieldDiff<>(from.allowMedia, to.allowMedia));
}
if (from.allowSystem != to.allowSystem) {
- addField("allowSystem", new FieldDiff<>(from.allowSystem, to.allowSystem));
+ addField(FIELD_ALLOW_SYSTEM, new FieldDiff<>(from.allowSystem, to.allowSystem));
}
if (from.allowCalls != to.allowCalls) {
- addField("allowCalls", new FieldDiff<>(from.allowCalls, to.allowCalls));
+ addField(FIELD_ALLOW_CALLS, new FieldDiff<>(from.allowCalls, to.allowCalls));
}
if (from.allowReminders != to.allowReminders) {
- addField("allowReminders",
+ addField(FIELD_ALLOW_REMINDERS,
new FieldDiff<>(from.allowReminders, to.allowReminders));
}
if (from.allowEvents != to.allowEvents) {
- addField("allowEvents", new FieldDiff<>(from.allowEvents, to.allowEvents));
+ addField(FIELD_ALLOW_EVENTS, new FieldDiff<>(from.allowEvents, to.allowEvents));
}
if (from.allowRepeatCallers != to.allowRepeatCallers) {
- addField("allowRepeatCallers",
+ addField(FIELD_ALLOW_REPEAT_CALLERS,
new FieldDiff<>(from.allowRepeatCallers, to.allowRepeatCallers));
}
if (from.allowMessages != to.allowMessages) {
- addField("allowMessages",
+ addField(FIELD_ALLOW_MESSAGES,
new FieldDiff<>(from.allowMessages, to.allowMessages));
}
if (from.allowConversations != to.allowConversations) {
- addField("allowConversations",
+ addField(FIELD_ALLOW_CONVERSATIONS,
new FieldDiff<>(from.allowConversations, to.allowConversations));
}
if (from.allowCallsFrom != to.allowCallsFrom) {
- addField("allowCallsFrom",
+ addField(FIELD_ALLOW_CALLS_FROM,
new FieldDiff<>(from.allowCallsFrom, to.allowCallsFrom));
}
if (from.allowMessagesFrom != to.allowMessagesFrom) {
- addField("allowMessagesFrom",
+ addField(FIELD_ALLOW_MESSAGES_FROM,
new FieldDiff<>(from.allowMessagesFrom, to.allowMessagesFrom));
}
if (from.allowConversationsFrom != to.allowConversationsFrom) {
- addField("allowConversationsFrom",
+ addField(FIELD_ALLOW_CONVERSATIONS_FROM,
new FieldDiff<>(from.allowConversationsFrom, to.allowConversationsFrom));
}
if (from.suppressedVisualEffects != to.suppressedVisualEffects) {
- addField("suppressedVisualEffects",
+ addField(FIELD_SUPPRESSED_VISUAL_EFFECTS,
new FieldDiff<>(from.suppressedVisualEffects, to.suppressedVisualEffects));
}
if (from.areChannelsBypassingDnd != to.areChannelsBypassingDnd) {
- addField("areChannelsBypassingDnd",
+ addField(FIELD_ARE_CHANNELS_BYPASSING_DND,
new FieldDiff<>(from.areChannelsBypassingDnd, to.areChannelsBypassingDnd));
}
@@ -366,7 +378,7 @@ public class ZenModeDiff {
sb.append(ZenModeConfig.sourceToString((int) diff.from()));
sb.append("->");
sb.append(ZenModeConfig.sourceToString((int) diff.to()));
- } else if (key.equals(ALLOW_CONVERSATIONS_FROM_FIELD)) {
+ } else if (key.equals(FIELD_ALLOW_CONVERSATIONS_FROM)) {
sb.append(key);
sb.append(":");
sb.append(ZenPolicy.conversationTypeToString((int) diff.from()));
@@ -428,6 +440,24 @@ public class ZenModeDiff {
* Diff class representing a change between two ZenRules.
*/
public static class RuleDiff extends BaseDiff {
+ public static final String FIELD_ENABLED = "enabled";
+ public static final String FIELD_SNOOZING = "snoozing";
+ public static final String FIELD_NAME = "name";
+ public static final String FIELD_ZEN_MODE = "zenMode";
+ public static final String FIELD_CONDITION_ID = "conditionId";
+ public static final String FIELD_CONDITION = "condition";
+ public static final String FIELD_COMPONENT = "component";
+ public static final String FIELD_CONFIGURATION_ACTIVITY = "configurationActivity";
+ public static final String FIELD_ID = "id";
+ public static final String FIELD_CREATION_TIME = "creationTime";
+ public static final String FIELD_ENABLER = "enabler";
+ public static final String FIELD_ZEN_POLICY = "zenPolicy";
+ public static final String FIELD_MODIFIED = "modified";
+ public static final String FIELD_PKG = "pkg";
+
+ // Special field to track whether this rule became active or inactive
+ FieldDiff<Boolean> mActiveDiff;
+
/**
* Create a RuleDiff representing the difference between two ZenRule objects.
* @param from previous ZenRule
@@ -440,54 +470,64 @@ public class ZenModeDiff {
if (from == null && to == null) {
return;
}
+
+ // Even if added or removed, there may be a change in whether or not it was active.
+ // This only applies to automatic rules.
+ boolean fromActive = from != null ? from.isAutomaticActive() : false;
+ boolean toActive = to != null ? to.isAutomaticActive() : false;
+ if (fromActive != toActive) {
+ mActiveDiff = new FieldDiff<>(fromActive, toActive);
+ }
+
// Return if the diff was added or removed
if (hasExistenceChange()) {
return;
}
if (from.enabled != to.enabled) {
- addField("enabled", new FieldDiff<>(from.enabled, to.enabled));
+ addField(FIELD_ENABLED, new FieldDiff<>(from.enabled, to.enabled));
}
if (from.snoozing != to.snoozing) {
- addField("snoozing", new FieldDiff<>(from.snoozing, to.snoozing));
+ addField(FIELD_SNOOZING, new FieldDiff<>(from.snoozing, to.snoozing));
}
if (!Objects.equals(from.name, to.name)) {
- addField("name", new FieldDiff<>(from.name, to.name));
+ addField(FIELD_NAME, new FieldDiff<>(from.name, to.name));
}
if (from.zenMode != to.zenMode) {
- addField("zenMode", new FieldDiff<>(from.zenMode, to.zenMode));
+ addField(FIELD_ZEN_MODE, new FieldDiff<>(from.zenMode, to.zenMode));
}
if (!Objects.equals(from.conditionId, to.conditionId)) {
- addField("conditionId", new FieldDiff<>(from.conditionId, to.conditionId));
+ addField(FIELD_CONDITION_ID, new FieldDiff<>(from.conditionId,
+ to.conditionId));
}
if (!Objects.equals(from.condition, to.condition)) {
- addField("condition", new FieldDiff<>(from.condition, to.condition));
+ addField(FIELD_CONDITION, new FieldDiff<>(from.condition, to.condition));
}
if (!Objects.equals(from.component, to.component)) {
- addField("component", new FieldDiff<>(from.component, to.component));
+ addField(FIELD_COMPONENT, new FieldDiff<>(from.component, to.component));
}
if (!Objects.equals(from.configurationActivity, to.configurationActivity)) {
- addField("configurationActivity", new FieldDiff<>(
+ addField(FIELD_CONFIGURATION_ACTIVITY, new FieldDiff<>(
from.configurationActivity, to.configurationActivity));
}
if (!Objects.equals(from.id, to.id)) {
- addField("id", new FieldDiff<>(from.id, to.id));
+ addField(FIELD_ID, new FieldDiff<>(from.id, to.id));
}
if (from.creationTime != to.creationTime) {
- addField("creationTime",
+ addField(FIELD_CREATION_TIME,
new FieldDiff<>(from.creationTime, to.creationTime));
}
if (!Objects.equals(from.enabler, to.enabler)) {
- addField("enabler", new FieldDiff<>(from.enabler, to.enabler));
+ addField(FIELD_ENABLER, new FieldDiff<>(from.enabler, to.enabler));
}
if (!Objects.equals(from.zenPolicy, to.zenPolicy)) {
- addField("zenPolicy", new FieldDiff<>(from.zenPolicy, to.zenPolicy));
+ addField(FIELD_ZEN_POLICY, new FieldDiff<>(from.zenPolicy, to.zenPolicy));
}
if (from.modified != to.modified) {
- addField("modified", new FieldDiff<>(from.modified, to.modified));
+ addField(FIELD_MODIFIED, new FieldDiff<>(from.modified, to.modified));
}
if (!Objects.equals(from.pkg, to.pkg)) {
- addField("pkg", new FieldDiff<>(from.pkg, to.pkg));
+ addField(FIELD_PKG, new FieldDiff<>(from.pkg, to.pkg));
}
}
@@ -536,7 +576,35 @@ public class ZenModeDiff {
sb.append(diff);
}
+ if (becameActive()) {
+ if (!first) {
+ sb.append(", ");
+ }
+ sb.append("(->active)");
+ } else if (becameInactive()) {
+ if (!first) {
+ sb.append(", ");
+ }
+ sb.append("(->inactive)");
+ }
+
return sb.append("}").toString();
}
+
+ /**
+ * Returns whether this diff indicates that this (automatic) rule became active.
+ */
+ public boolean becameActive() {
+ // if the "to" side is true, then it became active
+ return mActiveDiff != null && mActiveDiff.to();
+ }
+
+ /**
+ * Returns whether this diff indicates that this (automatic) rule became inactive.
+ */
+ public boolean becameInactive() {
+ // if the "to" side is false, then it became inactive
+ return mActiveDiff != null && !mActiveDiff.to();
+ }
}
}
diff --git a/core/proto/android/service/notification.proto b/core/proto/android/service/notification.proto
index f87d9109e7f8..17ca7c80707c 100644
--- a/core/proto/android/service/notification.proto
+++ b/core/proto/android/service/notification.proto
@@ -360,3 +360,11 @@ message DNDPolicyProto {
optional ConversationType allow_conversations_from = 19;
}
+
+// Enum identifying the type of rule that changed; values set to match ones used in the
+// DNDStateChanged proto.
+enum RuleType {
+ RULE_TYPE_UNKNOWN = 0;
+ RULE_TYPE_MANUAL = 1;
+ RULE_TYPE_AUTOMATIC = 2;
+}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index f0ab815db2c1..f83ba875d691 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1651,7 +1651,8 @@ public class NotificationManagerService extends SystemService {
if (Intent.ACTION_LOCALE_CHANGED.equals(intent.getAction())) {
// update system notification channels
SystemNotificationChannels.createAll(context);
- mZenModeHelper.updateDefaultZenRules();
+ mZenModeHelper.updateDefaultZenRules(Binder.getCallingUid(),
+ isCallerIsSystemOrSystemUi());
mPreferencesHelper.onLocaleChanged(context, ActivityManager.getCurrentUser());
}
}
@@ -2279,7 +2280,8 @@ public class NotificationManagerService extends SystemService {
mRankingHandler = rankingHandler;
mConditionProviders = conditionProviders;
mZenModeHelper = new ZenModeHelper(getContext(), mHandler.getLooper(), mConditionProviders,
- new SysUiStatsEvent.BuilderFactory());
+ new SysUiStatsEvent.BuilderFactory(), flagResolver,
+ new ZenModeEventLogger(mPackageManagerClient));
mZenModeHelper.addCallback(new ZenModeHelper.Callback() {
@Override
public void onConfigChanged() {
@@ -2861,7 +2863,8 @@ public class NotificationManagerService extends SystemService {
final NotificationChannel preUpdate =
mPreferencesHelper.getNotificationChannel(pkg, uid, channel.getId(), true);
- mPreferencesHelper.updateNotificationChannel(pkg, uid, channel, true);
+ mPreferencesHelper.updateNotificationChannel(pkg, uid, channel, true,
+ Binder.getCallingUid(), isCallerIsSystemOrSystemUi());
if (mPreferencesHelper.onlyHasDefaultChannel(pkg, uid)) {
mPermissionHelper.setNotificationPermission(pkg, UserHandle.getUserId(uid),
channel.getImportance() != IMPORTANCE_NONE, true);
@@ -2909,7 +2912,7 @@ public class NotificationManagerService extends SystemService {
final NotificationChannelGroup preUpdate =
mPreferencesHelper.getNotificationChannelGroup(group.getId(), pkg, uid);
mPreferencesHelper.createNotificationChannelGroup(pkg, uid, group,
- fromApp);
+ fromApp, Binder.getCallingUid(), isCallerIsSystemOrSystemUi());
if (!fromApp) {
maybeNotifyChannelGroupOwner(pkg, uid, preUpdate, group);
}
@@ -3874,7 +3877,8 @@ public class NotificationManagerService extends SystemService {
needsPolicyFileChange = mPreferencesHelper.createNotificationChannel(pkg, uid,
channel, true /* fromTargetApp */,
mConditionProviders.isPackageOrComponentAllowed(
- pkg, UserHandle.getUserId(uid)));
+ pkg, UserHandle.getUserId(uid)), Binder.getCallingUid(),
+ isCallerIsSystemOrSystemUi());
if (needsPolicyFileChange) {
mListeners.notifyNotificationChannelChanged(pkg,
UserHandle.getUserHandleForUid(uid),
@@ -4010,6 +4014,7 @@ public class NotificationManagerService extends SystemService {
public void deleteNotificationChannel(String pkg, String channelId) {
checkCallerIsSystemOrSameApp(pkg);
final int callingUid = Binder.getCallingUid();
+ final boolean isSystemOrSystemUi = isCallerIsSystemOrSystemUi();
final int callingUser = UserHandle.getUserId(callingUid);
if (NotificationChannel.DEFAULT_CHANNEL_ID.equals(channelId)) {
throw new IllegalArgumentException("Cannot delete default channel");
@@ -4019,7 +4024,7 @@ public class NotificationManagerService extends SystemService {
cancelAllNotificationsInt(MY_UID, MY_PID, pkg, channelId, 0, 0, true,
callingUser, REASON_CHANNEL_REMOVED, null);
boolean previouslyExisted = mPreferencesHelper.deleteNotificationChannel(
- pkg, callingUid, channelId);
+ pkg, callingUid, channelId, callingUid, isSystemOrSystemUi);
if (previouslyExisted) {
// Remove from both recent notification archive and notification history
mArchive.removeChannelNotifications(pkg, callingUser, channelId);
@@ -4052,6 +4057,7 @@ public class NotificationManagerService extends SystemService {
checkCallerIsSystemOrSameApp(pkg);
final int callingUid = Binder.getCallingUid();
+ final boolean isSystemOrSystemUi = isCallerIsSystemOrSystemUi();
NotificationChannelGroup groupToDelete =
mPreferencesHelper.getNotificationChannelGroupWithChannels(
pkg, callingUid, groupId, false);
@@ -4065,7 +4071,8 @@ public class NotificationManagerService extends SystemService {
enforceDeletingChannelHasNoUserInitiatedJob(pkg, userId, channelId);
}
List<NotificationChannel> deletedChannels =
- mPreferencesHelper.deleteNotificationChannelGroup(pkg, callingUid, groupId);
+ mPreferencesHelper.deleteNotificationChannelGroup(pkg, callingUid, groupId,
+ callingUid, isSystemOrSystemUi);
for (int i = 0; i < deletedChannels.size(); i++) {
final NotificationChannel deletedChannel = deletedChannels.get(i);
cancelAllNotificationsInt(MY_UID, MY_PID, pkg, deletedChannel.getId(), 0, 0,
@@ -4963,11 +4970,14 @@ public class NotificationManagerService extends SystemService {
@Override
public void requestInterruptionFilterFromListener(INotificationListener token,
int interruptionFilter) throws RemoteException {
+ final int callingUid = Binder.getCallingUid();
+ final boolean isSystemOrSystemUi = isCallerIsSystemOrSystemUi();
final long identity = Binder.clearCallingIdentity();
try {
synchronized (mNotificationLock) {
final ManagedServiceInfo info = mListeners.checkServiceTokenLocked(token);
- mZenModeHelper.requestFromListener(info.component, interruptionFilter);
+ mZenModeHelper.requestFromListener(info.component, interruptionFilter,
+ callingUid, isSystemOrSystemUi);
updateInterruptionFilterLocked();
}
} finally {
@@ -5007,9 +5017,12 @@ public class NotificationManagerService extends SystemService {
@Override
public void setZenMode(int mode, Uri conditionId, String reason) throws RemoteException {
enforceSystemOrSystemUI("INotificationManager.setZenMode");
+ final int callingUid = Binder.getCallingUid();
+ final boolean isSystemOrSystemUi = isCallerIsSystemOrSystemUi();
final long identity = Binder.clearCallingIdentity();
try {
- mZenModeHelper.setManualZenMode(mode, conditionId, null, reason);
+ mZenModeHelper.setManualZenMode(mode, conditionId, null, reason, callingUid,
+ isSystemOrSystemUi);
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -5056,7 +5069,8 @@ public class NotificationManagerService extends SystemService {
}
return mZenModeHelper.addAutomaticZenRule(rulePkg, automaticZenRule,
- "addAutomaticZenRule");
+ "addAutomaticZenRule", Binder.getCallingUid(),
+ isCallerIsSystemOrSystemUi());
}
@Override
@@ -5073,7 +5087,8 @@ public class NotificationManagerService extends SystemService {
enforcePolicyAccess(Binder.getCallingUid(), "updateAutomaticZenRule");
return mZenModeHelper.updateAutomaticZenRule(id, automaticZenRule,
- "updateAutomaticZenRule");
+ "updateAutomaticZenRule", Binder.getCallingUid(),
+ isCallerIsSystemOrSystemUi());
}
@Override
@@ -5082,7 +5097,8 @@ public class NotificationManagerService extends SystemService {
// Verify that they can modify zen rules.
enforcePolicyAccess(Binder.getCallingUid(), "removeAutomaticZenRule");
- return mZenModeHelper.removeAutomaticZenRule(id, "removeAutomaticZenRule");
+ return mZenModeHelper.removeAutomaticZenRule(id, "removeAutomaticZenRule",
+ Binder.getCallingUid(), isCallerIsSystemOrSystemUi());
}
@Override
@@ -5091,7 +5107,8 @@ public class NotificationManagerService extends SystemService {
enforceSystemOrSystemUI("removeAutomaticZenRules");
return mZenModeHelper.removeAutomaticZenRules(packageName,
- packageName + "|removeAutomaticZenRules");
+ packageName + "|removeAutomaticZenRules", Binder.getCallingUid(),
+ isCallerIsSystemOrSystemUi());
}
@Override
@@ -5109,7 +5126,8 @@ public class NotificationManagerService extends SystemService {
enforcePolicyAccess(Binder.getCallingUid(), "setAutomaticZenRuleState");
- mZenModeHelper.setAutomaticZenRuleState(id, condition);
+ mZenModeHelper.setAutomaticZenRuleState(id, condition, Binder.getCallingUid(),
+ isCallerIsSystemOrSystemUi());
}
@Override
@@ -5117,9 +5135,12 @@ public class NotificationManagerService extends SystemService {
enforcePolicyAccess(pkg, "setInterruptionFilter");
final int zen = NotificationManager.zenModeFromInterruptionFilter(filter, -1);
if (zen == -1) throw new IllegalArgumentException("Invalid filter: " + filter);
+ final int callingUid = Binder.getCallingUid();
+ final boolean isSystemOrSystemUi = isCallerIsSystemOrSystemUi();
final long identity = Binder.clearCallingIdentity();
try {
- mZenModeHelper.setManualZenMode(zen, null, pkg, "setInterruptionFilter");
+ mZenModeHelper.setManualZenMode(zen, null, pkg, "setInterruptionFilter",
+ callingUid, isSystemOrSystemUi);
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -5420,6 +5441,7 @@ public class NotificationManagerService extends SystemService {
public void setNotificationPolicy(String pkg, Policy policy) {
enforcePolicyAccess(pkg, "setNotificationPolicy");
int callingUid = Binder.getCallingUid();
+ boolean isSystemOrSystemUi = isCallerIsSystemOrSystemUi();
final long identity = Binder.clearCallingIdentity();
try {
final ApplicationInfo applicationInfo = mPackageManager.getApplicationInfo(pkg,
@@ -5459,7 +5481,7 @@ public class NotificationManagerService extends SystemService {
policy.priorityCallSenders, policy.priorityMessageSenders,
newVisualEffects, policy.priorityConversationSenders);
ZenLog.traceSetNotificationPolicy(pkg, applicationInfo.targetSdkVersion, policy);
- mZenModeHelper.setNotificationPolicy(policy);
+ mZenModeHelper.setNotificationPolicy(policy, callingUid, isSystemOrSystemUi);
} catch (RemoteException e) {
} finally {
Binder.restoreCallingIdentity(identity);
@@ -6697,7 +6719,8 @@ public class NotificationManagerService extends SystemService {
channel.setUserVisibleTaskShown(true);
}
mPreferencesHelper.updateNotificationChannel(
- pkg, notificationUid, channel, false);
+ pkg, notificationUid, channel, false, callingUid,
+ isCallerIsSystemOrSystemUi());
r.updateNotificationChannel(channel);
} else if (!channel.isUserVisibleTaskShown() && !TextUtils.isEmpty(channelId)
&& !NotificationChannel.DEFAULT_CHANNEL_ID.equals(channelId)) {
@@ -6770,7 +6793,8 @@ public class NotificationManagerService extends SystemService {
mHistoryManager.deleteConversations(pkg, uid, shortcuts);
List<String> deletedChannelIds =
- mPreferencesHelper.deleteConversations(pkg, uid, shortcuts);
+ mPreferencesHelper.deleteConversations(pkg, uid, shortcuts,
+ /* callingUid */ Process.SYSTEM_UID, /* is system */ true);
for (String channelId : deletedChannelIds) {
cancelAllNotificationsInt(MY_UID, MY_PID, pkg, channelId, 0, 0, true,
UserHandle.getUserId(uid), REASON_CHANNEL_REMOVED,
@@ -9999,7 +10023,8 @@ public class NotificationManagerService extends SystemService {
return isUidSystemOrPhone(Binder.getCallingUid());
}
- private boolean isCallerIsSystemOrSystemUi() {
+ @VisibleForTesting
+ protected boolean isCallerIsSystemOrSystemUi() {
if (isCallerSystemOrPhone()) {
return true;
}
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 2460ce56f165..4399a3ca46c5 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -51,6 +51,7 @@ import android.metrics.LogMaker;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
+import android.os.Process;
import android.os.UserHandle;
import android.provider.Settings;
import android.service.notification.ConversationChannelWrapper;
@@ -217,7 +218,7 @@ public class PreferencesHelper implements RankingConfig {
updateBadgingEnabled();
updateBubblesEnabled();
updateMediaNotificationFilteringEnabled();
- syncChannelsBypassingDnd();
+ syncChannelsBypassingDnd(Process.SYSTEM_UID, true); // init comes from system
}
public void readXml(TypedXmlPullParser parser, boolean forRestore, int userId)
@@ -834,7 +835,7 @@ public class PreferencesHelper implements RankingConfig {
@Override
public void createNotificationChannelGroup(String pkg, int uid, NotificationChannelGroup group,
- boolean fromTargetApp) {
+ boolean fromTargetApp, int callingUid, boolean fromSystemOrSystemUi) {
Objects.requireNonNull(pkg);
Objects.requireNonNull(group);
Objects.requireNonNull(group.getId());
@@ -880,13 +881,14 @@ public class PreferencesHelper implements RankingConfig {
r.groups.put(group.getId(), group);
}
if (needsDndChange) {
- updateChannelsBypassingDnd();
+ updateChannelsBypassingDnd(callingUid, fromSystemOrSystemUi);
}
}
@Override
public boolean createNotificationChannel(String pkg, int uid, NotificationChannel channel,
- boolean fromTargetApp, boolean hasDndAccess) {
+ boolean fromTargetApp, boolean hasDndAccess, int callingUid,
+ boolean fromSystemOrSystemUi) {
Objects.requireNonNull(pkg);
Objects.requireNonNull(channel);
Objects.requireNonNull(channel.getId());
@@ -1027,7 +1029,7 @@ public class PreferencesHelper implements RankingConfig {
}
if (needsDndChange) {
- updateChannelsBypassingDnd();
+ updateChannelsBypassingDnd(callingUid, fromSystemOrSystemUi);
}
return needsPolicyFileChange;
@@ -1056,7 +1058,7 @@ public class PreferencesHelper implements RankingConfig {
@Override
public void updateNotificationChannel(String pkg, int uid, NotificationChannel updatedChannel,
- boolean fromUser) {
+ boolean fromUser, int callingUid, boolean fromSystemOrSystemUi) {
Objects.requireNonNull(updatedChannel);
Objects.requireNonNull(updatedChannel.getId());
boolean changed = false;
@@ -1112,7 +1114,7 @@ public class PreferencesHelper implements RankingConfig {
}
}
if (needsDndChange) {
- updateChannelsBypassingDnd();
+ updateChannelsBypassingDnd(callingUid, fromSystemOrSystemUi);
}
if (changed) {
updateConfig();
@@ -1188,7 +1190,8 @@ public class PreferencesHelper implements RankingConfig {
}
@Override
- public boolean deleteNotificationChannel(String pkg, int uid, String channelId) {
+ public boolean deleteNotificationChannel(String pkg, int uid, String channelId,
+ int callingUid, boolean fromSystemOrSystemUi) {
boolean deletedChannel = false;
boolean channelBypassedDnd = false;
synchronized (mPackagePreferences) {
@@ -1203,7 +1206,7 @@ public class PreferencesHelper implements RankingConfig {
}
}
if (channelBypassedDnd) {
- updateChannelsBypassingDnd();
+ updateChannelsBypassingDnd(callingUid, fromSystemOrSystemUi);
}
return deletedChannel;
}
@@ -1394,7 +1397,7 @@ public class PreferencesHelper implements RankingConfig {
}
public List<NotificationChannel> deleteNotificationChannelGroup(String pkg, int uid,
- String groupId) {
+ String groupId, int callingUid, boolean fromSystemOrSystemUi) {
List<NotificationChannel> deletedChannels = new ArrayList<>();
boolean groupBypassedDnd = false;
synchronized (mPackagePreferences) {
@@ -1420,7 +1423,7 @@ public class PreferencesHelper implements RankingConfig {
}
}
if (groupBypassedDnd) {
- updateChannelsBypassingDnd();
+ updateChannelsBypassingDnd(callingUid, fromSystemOrSystemUi);
}
return deletedChannels;
}
@@ -1543,7 +1546,7 @@ public class PreferencesHelper implements RankingConfig {
}
public @NonNull List<String> deleteConversations(String pkg, int uid,
- Set<String> conversationIds) {
+ Set<String> conversationIds, int callingUid, boolean fromSystemOrSystemUi) {
List<String> deletedChannelIds = new ArrayList<>();
synchronized (mPackagePreferences) {
PackagePreferences r = getPackagePreferencesLocked(pkg, uid);
@@ -1568,7 +1571,7 @@ public class PreferencesHelper implements RankingConfig {
}
}
if (!deletedChannelIds.isEmpty() && mAreChannelsBypassingDnd) {
- updateChannelsBypassingDnd();
+ updateChannelsBypassingDnd(callingUid, fromSystemOrSystemUi);
}
return deletedChannelIds;
}
@@ -1673,18 +1676,18 @@ public class PreferencesHelper implements RankingConfig {
* Syncs {@link #mAreChannelsBypassingDnd} with the current user's notification policy before
* updating
*/
- private void syncChannelsBypassingDnd() {
+ private void syncChannelsBypassingDnd(int callingUid, boolean fromSystemOrSystemUi) {
mAreChannelsBypassingDnd = (mZenModeHelper.getNotificationPolicy().state
& NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND) == 1;
- updateChannelsBypassingDnd();
+ updateChannelsBypassingDnd(callingUid, fromSystemOrSystemUi);
}
/**
* Updates the user's NotificationPolicy based on whether the current userId
* has channels bypassing DND
*/
- private void updateChannelsBypassingDnd() {
+ private void updateChannelsBypassingDnd(int callingUid, boolean fromSystemOrSystemUi) {
ArraySet<Pair<String, Integer>> candidatePkgs = new ArraySet<>();
final int currentUserId = getCurrentUser();
@@ -1714,7 +1717,7 @@ public class PreferencesHelper implements RankingConfig {
boolean haveBypassingApps = candidatePkgs.size() > 0;
if (mAreChannelsBypassingDnd != haveBypassingApps) {
mAreChannelsBypassingDnd = haveBypassingApps;
- updateZenPolicy(mAreChannelsBypassingDnd);
+ updateZenPolicy(mAreChannelsBypassingDnd, callingUid, fromSystemOrSystemUi);
}
}
@@ -1739,14 +1742,15 @@ public class PreferencesHelper implements RankingConfig {
return true;
}
- public void updateZenPolicy(boolean areChannelsBypassingDnd) {
+ public void updateZenPolicy(boolean areChannelsBypassingDnd, int callingUid,
+ boolean fromSystemOrSystemUi) {
NotificationManager.Policy policy = mZenModeHelper.getNotificationPolicy();
mZenModeHelper.setNotificationPolicy(new NotificationManager.Policy(
policy.priorityCategories, policy.priorityCallSenders,
policy.priorityMessageSenders, policy.suppressedVisualEffects,
(areChannelsBypassingDnd ? NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND
: 0),
- policy.priorityConversationSenders));
+ policy.priorityConversationSenders), callingUid, fromSystemOrSystemUi);
}
public boolean areChannelsBypassingDnd() {
diff --git a/services/core/java/com/android/server/notification/RankingConfig.java b/services/core/java/com/android/server/notification/RankingConfig.java
index 3e9d90c440b6..fec359198e88 100644
--- a/services/core/java/com/android/server/notification/RankingConfig.java
+++ b/services/core/java/com/android/server/notification/RankingConfig.java
@@ -39,19 +39,21 @@ public interface RankingConfig {
Collection<NotificationChannelGroup> getNotificationChannelGroups(String pkg,
int uid);
void createNotificationChannelGroup(String pkg, int uid, NotificationChannelGroup group,
- boolean fromTargetApp);
+ boolean fromTargetApp, int callingUid, boolean isSystemOrSystemUi);
ParceledListSlice<NotificationChannelGroup> getNotificationChannelGroups(String pkg,
int uid, boolean includeDeleted, boolean includeNonGrouped, boolean includeEmpty);
boolean createNotificationChannel(String pkg, int uid, NotificationChannel channel,
- boolean fromTargetApp, boolean hasDndAccess);
- void updateNotificationChannel(String pkg, int uid, NotificationChannel channel,
- boolean fromUser);
+ boolean fromTargetApp, boolean hasDndAccess, int callingUid,
+ boolean isSystemOrSystemUi);
+ void updateNotificationChannel(String pkg, int uid, NotificationChannel updatedChannel,
+ boolean fromUser, int callingUid, boolean fromSystemOrSystemUi);
NotificationChannel getNotificationChannel(String pkg, int uid, String channelId,
boolean includeDeleted);
NotificationChannel getConversationNotificationChannel(String pkg, int uid, String channelId,
String conversationId, boolean returnParentIfNoConversationChannel,
boolean includeDeleted);
- boolean deleteNotificationChannel(String pkg, int uid, String channelId);
+ boolean deleteNotificationChannel(String pkg, int uid, String channelId,
+ int callingUid, boolean fromSystemOrSystemUi);
void permanentlyDeleteNotificationChannel(String pkg, int uid, String channelId);
void permanentlyDeleteNotificationChannels(String pkg, int uid);
ParceledListSlice<NotificationChannel> getNotificationChannels(String pkg, int uid,
diff --git a/services/core/java/com/android/server/notification/ZenModeConditions.java b/services/core/java/com/android/server/notification/ZenModeConditions.java
index 50b4d438984c..6ecd799bf8e6 100644
--- a/services/core/java/com/android/server/notification/ZenModeConditions.java
+++ b/services/core/java/com/android/server/notification/ZenModeConditions.java
@@ -18,6 +18,8 @@ package com.android.server.notification;
import android.content.ComponentName;
import android.net.Uri;
+import android.os.Binder;
+import android.os.Process;
import android.service.notification.Condition;
import android.service.notification.IConditionProvider;
import android.service.notification.ZenModeConfig;
@@ -108,7 +110,9 @@ public class ZenModeConditions implements ConditionProviders.Callback {
@Override
public void onServiceAdded(ComponentName component) {
if (DEBUG) Log.d(TAG, "onServiceAdded " + component);
- mHelper.setConfig(mHelper.getConfig(), component, "zmc.onServiceAdded:" + component);
+ final int callingUid = Binder.getCallingUid();
+ mHelper.setConfig(mHelper.getConfig(), component, "zmc.onServiceAdded:" + component,
+ callingUid, callingUid == Process.SYSTEM_UID);
}
@Override
@@ -116,7 +120,9 @@ public class ZenModeConditions implements ConditionProviders.Callback {
if (DEBUG) Log.d(TAG, "onConditionChanged " + id + " " + condition);
ZenModeConfig config = mHelper.getConfig();
if (config == null) return;
- mHelper.setAutomaticZenRuleState(id, condition);
+ final int callingUid = Binder.getCallingUid();
+ mHelper.setAutomaticZenRuleState(id, condition, callingUid,
+ callingUid == Process.SYSTEM_UID);
}
// Only valid for CPS backed rules
diff --git a/services/core/java/com/android/server/notification/ZenModeEventLogger.java b/services/core/java/com/android/server/notification/ZenModeEventLogger.java
new file mode 100644
index 000000000000..1641d4a6ed46
--- /dev/null
+++ b/services/core/java/com/android/server/notification/ZenModeEventLogger.java
@@ -0,0 +1,611 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.notification;
+
+import static android.app.NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND;
+import static android.provider.Settings.Global.ZEN_MODE_OFF;
+import static android.service.notification.NotificationServiceProto.RULE_TYPE_AUTOMATIC;
+import static android.service.notification.NotificationServiceProto.RULE_TYPE_MANUAL;
+import static android.service.notification.NotificationServiceProto.RULE_TYPE_UNKNOWN;
+
+import android.annotation.NonNull;
+import android.app.NotificationManager;
+import android.content.pm.PackageManager;
+import android.os.Process;
+import android.service.notification.DNDPolicyProto;
+import android.service.notification.ZenModeConfig;
+import android.service.notification.ZenModeDiff;
+import android.service.notification.ZenPolicy;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.util.Pair;
+import android.util.Slog;
+import android.util.proto.ProtoOutputStream;
+
+import com.android.internal.logging.UiEvent;
+import com.android.internal.logging.UiEventLogger;
+import com.android.internal.util.FrameworkStatsLog;
+
+import java.io.ByteArrayOutputStream;
+import java.util.Objects;
+
+/**
+ * Class for writing DNDStateChanged atoms to the statsd log.
+ * Use ZenModeEventLoggerFake for testing.
+ */
+class ZenModeEventLogger {
+ private static final String TAG = "ZenModeEventLogger";
+
+ // Placeholder int for unknown zen mode, to distinguish from "off".
+ static final int ZEN_MODE_UNKNOWN = -1;
+
+ // Object for tracking config changes and policy changes associated with an overall zen
+ // mode change.
+ ZenModeEventLogger.ZenStateChanges mChangeState = new ZenModeEventLogger.ZenStateChanges();
+
+ private PackageManager mPm;
+
+ ZenModeEventLogger(PackageManager pm) {
+ mPm = pm;
+ }
+
+ /**
+ * Enum used to log the type of DND state changed events.
+ * These use UiEvent IDs for ease of integrating with other UiEvents.
+ */
+ enum ZenStateChangedEvent implements UiEventLogger.UiEventEnum {
+ @UiEvent(doc = "DND was turned on; may additionally include policy change.")
+ DND_TURNED_ON(1368),
+ @UiEvent(doc = "DND was turned off; may additionally include policy change.")
+ DND_TURNED_OFF(1369),
+ @UiEvent(doc = "DND policy was changed but the zen mode did not change.")
+ DND_POLICY_CHANGED(1370),
+ @UiEvent(doc = "Change in DND automatic rules active, without changing mode or policy.")
+ DND_ACTIVE_RULES_CHANGED(1371);
+
+ private final int mId;
+
+ ZenStateChangedEvent(int id) {
+ mId = id;
+ }
+
+ @Override
+ public int getId() {
+ return mId;
+ }
+ }
+
+ /**
+ * Potentially log a zen mode change if the provided config and policy changes warrant it.
+ *
+ * @param prevInfo ZenModeInfo (zen mode setting, config, policy) prior to this change
+ * @param newInfo ZenModeInfo after this change takes effect
+ * @param callingUid the calling UID associated with the change; may be used to attribute the
+ * change to a particular package or determine if this is a user action
+ * @param fromSystemOrSystemUi whether the calling UID is either system UID or system UI
+ */
+ public final void maybeLogZenChange(ZenModeInfo prevInfo, ZenModeInfo newInfo, int callingUid,
+ boolean fromSystemOrSystemUi) {
+ mChangeState.init(prevInfo, newInfo, callingUid, fromSystemOrSystemUi);
+ if (mChangeState.shouldLogChanges()) {
+ maybeReassignCallingUid();
+ logChanges();
+ }
+
+ // clear out the state for a fresh start next time
+ mChangeState = new ZenModeEventLogger.ZenStateChanges();
+ }
+
+ /**
+ * Reassign callingUid in mChangeState if we have more specific information that warrants it
+ * (for instance, if the change is automatic and due to an automatic rule change).
+ */
+ private void maybeReassignCallingUid() {
+ int userId = Process.INVALID_UID;
+ String packageName = null;
+
+ // For a manual rule, we consider reassigning the UID only when the call seems to come from
+ // the system and there is a non-null enabler in the new config.
+ // We don't consider the manual rule in the old config because if a manual rule is turning
+ // off with a call from system, that could easily be a user action to explicitly turn it off
+ if (mChangeState.getChangedRuleType() == RULE_TYPE_MANUAL) {
+ if (!mChangeState.mFromSystemOrSystemUi
+ || mChangeState.getNewManualRuleEnabler() == null) {
+ return;
+ }
+ packageName = mChangeState.getNewManualRuleEnabler();
+ userId = mChangeState.mNewConfig.user; // mNewConfig must not be null if enabler exists
+ }
+
+ // The conditions where we should consider reassigning UID for an automatic rule change:
+ // - we've determined it's not a user action
+ // - our current best guess is that the calling uid is system/sysui
+ if (mChangeState.getChangedRuleType() == RULE_TYPE_AUTOMATIC) {
+ if (mChangeState.getIsUserAction() || !mChangeState.mFromSystemOrSystemUi) {
+ return;
+ }
+
+ // Only try to get the package UID if there's exactly one changed automatic rule. If
+ // there's more than one that changes simultaneously, this is likely to be a boot and
+ // we can leave it attributed to system.
+ ArrayMap<String, ZenModeDiff.RuleDiff> changedRules =
+ mChangeState.getChangedAutomaticRules();
+ if (changedRules.size() != 1) {
+ return;
+ }
+ Pair<String, Integer> ruleInfo = mChangeState.getRulePackageAndUser(
+ changedRules.keyAt(0),
+ changedRules.valueAt(0));
+
+ if (ruleInfo == null || ruleInfo.first.equals(ZenModeConfig.SYSTEM_AUTHORITY)) {
+ // leave system rules as-is
+ return;
+ }
+
+ packageName = ruleInfo.first;
+ userId = ruleInfo.second;
+ }
+
+ if (userId == Process.INVALID_UID || packageName == null) {
+ // haven't found anything to look up.
+ return;
+ }
+
+ try {
+ int uid = mPm.getPackageUidAsUser(packageName, userId);
+ mChangeState.mCallingUid = uid;
+ } catch (PackageManager.NameNotFoundException e) {
+ Slog.e(TAG, "unable to find package name " + packageName + " " + userId);
+ }
+ }
+
+ /**
+ * Actually log all changes stored in the current change state to statsd output. This method
+ * should not be used directly by callers; visible for override by subclasses.
+ */
+ void logChanges() {
+ FrameworkStatsLog.write(FrameworkStatsLog.DND_STATE_CHANGED,
+ /* int32 event_id = 1 */ mChangeState.getEventId().getId(),
+ /* android.stats.dnd.ZenMode new_mode = 2 */ mChangeState.mNewZenMode,
+ /* android.stats.dnd.ZenMode previous_mode = 3 */ mChangeState.mPrevZenMode,
+ /* android.stats.dnd.RuleType rule_type = 4 */ mChangeState.getChangedRuleType(),
+ /* int32 num_rules_active = 5 */ mChangeState.getNumRulesActive(),
+ /* bool user_action = 6 */ mChangeState.getIsUserAction(),
+ /* int32 package_uid = 7 */ mChangeState.getPackageUid(),
+ /* DNDPolicyProto current_policy = 8 */ mChangeState.getDNDPolicyProto(),
+ /* bool are_channels_bypassing = 9 */ mChangeState.getAreChannelsBypassing());
+ }
+
+ /**
+ * Helper class for storing the set of information about a zen mode configuration at a specific
+ * time: the current zen mode setting, ZenModeConfig, and consolidated policy (a result of
+ * evaluating all active zen rules at the time).
+ */
+ public static class ZenModeInfo {
+ final int mZenMode;
+ final ZenModeConfig mConfig;
+ final NotificationManager.Policy mPolicy;
+
+ ZenModeInfo(int zenMode, ZenModeConfig config, NotificationManager.Policy policy) {
+ mZenMode = zenMode;
+ // Store a copy of configs & policies to not accidentally pick up any further changes
+ mConfig = config != null ? config.copy() : null;
+ mPolicy = policy != null ? policy.copy() : null;
+ }
+ }
+
+ /**
+ * Class used to track overall changes in zen mode, since changes such as config updates happen
+ * in multiple stages (first changing the config, then re-evaluating zen mode and the
+ * consolidated policy), and which contains the logic of 1) whether to log the zen mode change
+ * and 2) deriving the properties to log.
+ */
+ static class ZenStateChanges {
+ int mPrevZenMode = ZEN_MODE_UNKNOWN;
+ int mNewZenMode = ZEN_MODE_UNKNOWN;
+ ZenModeConfig mPrevConfig, mNewConfig;
+ NotificationManager.Policy mPrevPolicy, mNewPolicy;
+ int mCallingUid = Process.INVALID_UID;
+ boolean mFromSystemOrSystemUi = false;
+
+ private void init(ZenModeInfo prevInfo, ZenModeInfo newInfo, int callingUid,
+ boolean fromSystemOrSystemUi) {
+ // previous & new may be the same -- that would indicate that zen mode hasn't changed.
+ mPrevZenMode = prevInfo.mZenMode;
+ mNewZenMode = newInfo.mZenMode;
+ mPrevConfig = prevInfo.mConfig;
+ mNewConfig = newInfo.mConfig;
+ mPrevPolicy = prevInfo.mPolicy;
+ mNewPolicy = newInfo.mPolicy;
+ mCallingUid = callingUid;
+ mFromSystemOrSystemUi = fromSystemOrSystemUi;
+ }
+
+ /**
+ * Returns whether there is a policy diff represented by this change. This doesn't count
+ * if the previous policy is null, as that would indicate having no information rather than
+ * having no previous policy.
+ */
+ private boolean hasPolicyDiff() {
+ return mPrevPolicy != null && !Objects.equals(mPrevPolicy, mNewPolicy);
+ }
+
+ /**
+ * Whether the set of changes encapsulated in this state should be logged. This should only
+ * be called after methods to store config and zen mode info.
+ */
+ private boolean shouldLogChanges() {
+ // Did zen mode change from off to on or vice versa? If so, log in all cases.
+ if (zenModeFlipped()) {
+ return true;
+ }
+
+ // If zen mode didn't change, did the policy or number of active rules change? We only
+ // care about changes that take effect while zen mode is on, so make sure the current
+ // zen mode is not "OFF"
+ if (mNewZenMode == ZEN_MODE_OFF) {
+ return false;
+ }
+ return hasPolicyDiff() || hasRuleCountDiff();
+ }
+
+ // Does the difference in zen mode go from off to on or vice versa?
+ private boolean zenModeFlipped() {
+ if (mPrevZenMode == mNewZenMode) {
+ return false;
+ }
+
+ // then it flipped if one or the other is off. (there's only one off state; there are
+ // multiple states one could consider "on")
+ return mPrevZenMode == ZEN_MODE_OFF || mNewZenMode == ZEN_MODE_OFF;
+ }
+
+ // Helper methods below to fill out the atom contents below:
+
+ /**
+ * Based on the changes, returns the event ID corresponding to the change. Assumes that
+ * shouldLogChanges() is true and already checked (and will Log.wtf if not true).
+ */
+ ZenStateChangedEvent getEventId() {
+ if (!shouldLogChanges()) {
+ Log.wtf(TAG, "attempt to get DNDStateChanged fields without shouldLog=true");
+ }
+ if (zenModeFlipped()) {
+ if (mPrevZenMode == ZEN_MODE_OFF) {
+ return ZenStateChangedEvent.DND_TURNED_ON;
+ } else {
+ return ZenStateChangedEvent.DND_TURNED_OFF;
+ }
+ }
+
+ // zen mode didn't change; we must be here because of a policy change or rule change
+ if (hasPolicyDiff() || hasChannelsBypassingDiff()) {
+ return ZenStateChangedEvent.DND_POLICY_CHANGED;
+ }
+
+ // Also no policy change, so it has to be a rule change
+ return ZenStateChangedEvent.DND_ACTIVE_RULES_CHANGED;
+ }
+
+ /**
+ * Based on the config diff, determine which type of rule changed (or "unknown" to indicate
+ * unknown or neither).
+ * In the (probably somewhat unusual) case that there are both, manual takes precedence over
+ * automatic.
+ */
+ int getChangedRuleType() {
+ ZenModeDiff.ConfigDiff diff = new ZenModeDiff.ConfigDiff(mPrevConfig, mNewConfig);
+ if (!diff.hasDiff()) {
+ // no diff in the config. this probably shouldn't happen, but we can consider it
+ // unknown (given that if zen mode changes it is usually accompanied by some rule
+ // turning on or off, which should cause a config diff).
+ return RULE_TYPE_UNKNOWN;
+ }
+
+ ZenModeDiff.RuleDiff manualDiff = diff.getManualRuleDiff();
+ if (manualDiff != null && manualDiff.hasDiff()) {
+ // a diff in the manual rule doesn't *necessarily* mean that it's responsible for
+ // the change -- only if it's been added or removed.
+ if (manualDiff.wasAdded() || manualDiff.wasRemoved()) {
+ return RULE_TYPE_MANUAL;
+ }
+ }
+
+ ArrayMap<String, ZenModeDiff.RuleDiff> autoDiffs = diff.getAllAutomaticRuleDiffs();
+ if (autoDiffs != null) {
+ for (ZenModeDiff.RuleDiff d : autoDiffs.values()) {
+ if (d != null && d.hasDiff()) {
+ // If the rule became active or inactive, then this is probably relevant.
+ if (d.becameActive() || d.becameInactive()) {
+ return RULE_TYPE_AUTOMATIC;
+ }
+ }
+ }
+ }
+ return RULE_TYPE_UNKNOWN;
+ }
+
+ /**
+ * Returns whether the previous config and new config have a different number of active
+ * automatic or manual rules.
+ */
+ private boolean hasRuleCountDiff() {
+ return numActiveRulesInConfig(mPrevConfig) != numActiveRulesInConfig(mNewConfig);
+ }
+
+ /**
+ * Get the number of active rules represented in a zen mode config. Because this is based
+ * on a config, this does not take into account the zen mode at the time of the config,
+ * which means callers need to take the zen mode into account for whether the rules are
+ * actually active.
+ */
+ int numActiveRulesInConfig(ZenModeConfig config) {
+ // If the config is null, return early
+ if (config == null) {
+ return 0;
+ }
+
+ int rules = 0;
+ // Loop through the config and check:
+ // - does a manual rule exist? (if it's non-null, it's active)
+ // - how many automatic rules are active, as defined by isAutomaticActive()?
+ if (config.manualRule != null) {
+ rules++;
+ }
+
+ if (config.automaticRules != null) {
+ for (ZenModeConfig.ZenRule rule : config.automaticRules.values()) {
+ if (rule != null && rule.isAutomaticActive()) {
+ rules++;
+ }
+ }
+ }
+ return rules;
+ }
+
+ // Determine the number of (automatic & manual) rules active after the change takes place.
+ int getNumRulesActive() {
+ // If the zen mode has turned off, that means nothing can be active.
+ if (mNewZenMode == ZEN_MODE_OFF) {
+ return 0;
+ }
+ return numActiveRulesInConfig(mNewConfig);
+ }
+
+ /**
+ * Return our best guess as to whether the changes observed are due to a user action.
+ * Note that this won't be 100% accurate as we can't necessarily distinguish between a
+ * system uid call indicating "user interacted with Settings" vs "a system app changed
+ * something automatically".
+ */
+ boolean getIsUserAction() {
+ // Approach:
+ // - if manual rule turned on or off, the calling UID is system, and the new manual
+ // rule does not have an enabler set, guess that this is likely to be a user action.
+ // This may represent a system app turning on DND automatically, but we guess "user"
+ // in this case.
+ // - note that this has a known failure mode of "manual rule turning off
+ // automatically after the default time runs out". We currently have no way
+ // of distinguishing this case from a user manually turning off the rule.
+ // - the reason for checking the enabler field is that a call may look like it's
+ // coming from a system UID, but if an enabler is set then the request came
+ // from an external source. "enabler" will be blank when manual rule is turned
+ // on from Quick Settings or Settings.
+ // - if an automatic rule's state changes in whether it is "enabled", then
+ // that is probably a user action.
+ // - if an automatic rule goes from "not snoozing" to "snoozing", that is probably
+ // a user action; that means that the user temporarily turned off DND associated
+ // with that rule.
+ // - if an automatic rule becomes active but does *not* change in its enabled state
+ // (covered by a previous case anyway), we guess that this is an automatic change.
+ // - if a rule is added or removed and the call comes from the system, we guess that
+ // this is a user action (as system rules can't be added or removed without a user
+ // action).
+ switch (getChangedRuleType()) {
+ case RULE_TYPE_MANUAL:
+ // TODO(b/278888961): Distinguish the automatically-turned-off state
+ return mFromSystemOrSystemUi && (getNewManualRuleEnabler() == null);
+ case RULE_TYPE_AUTOMATIC:
+ for (ZenModeDiff.RuleDiff d : getChangedAutomaticRules().values()) {
+ if (d.wasAdded() || d.wasRemoved()) {
+ // If the change comes from system, a rule being added/removed indicates
+ // a likely user action. From an app, it's harder to know for sure.
+ return mFromSystemOrSystemUi;
+ }
+ ZenModeDiff.FieldDiff enabled = d.getDiffForField(
+ ZenModeDiff.RuleDiff.FIELD_ENABLED);
+ if (enabled != null && enabled.hasDiff()) {
+ return true;
+ }
+ ZenModeDiff.FieldDiff snoozing = d.getDiffForField(
+ ZenModeDiff.RuleDiff.FIELD_SNOOZING);
+ if (snoozing != null && snoozing.hasDiff() && (boolean) snoozing.to()) {
+ return true;
+ }
+ }
+ // If the change was in an automatic rule and none of the "probably triggered
+ // by a user" cases apply, then it's probably an automatic change.
+ return false;
+ case RULE_TYPE_UNKNOWN:
+ default:
+ }
+
+ // If the change wasn't in a rule, but was in the zen policy: consider to be user action
+ // if the calling uid is system
+ if (hasPolicyDiff() || hasChannelsBypassingDiff()) {
+ return mCallingUid == Process.SYSTEM_UID;
+ }
+
+ // don't know, or none of the other things triggered; assume not a user action
+ return false;
+ }
+
+ /**
+ * Get the package UID associated with this change, which is just the calling UID for the
+ * relevant method changes. This may get reset by ZenModeEventLogger, which has access to
+ * a PackageManager to get an appropriate UID for a package.
+ */
+ int getPackageUid() {
+ return mCallingUid;
+ }
+
+ /**
+ * Convert the new policy to a DNDPolicyProto format for output in logs.
+ */
+ byte[] getDNDPolicyProto() {
+ ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+ ProtoOutputStream proto = new ProtoOutputStream(bytes);
+
+ // While we don't expect this to be null at any point, guard against any weird cases.
+ if (mNewPolicy != null) {
+ proto.write(DNDPolicyProto.CALLS, toState(mNewPolicy.allowCalls()));
+ proto.write(DNDPolicyProto.REPEAT_CALLERS,
+ toState(mNewPolicy.allowRepeatCallers()));
+ proto.write(DNDPolicyProto.MESSAGES, toState(mNewPolicy.allowMessages()));
+ proto.write(DNDPolicyProto.CONVERSATIONS, toState(mNewPolicy.allowConversations()));
+ proto.write(DNDPolicyProto.REMINDERS, toState(mNewPolicy.allowReminders()));
+ proto.write(DNDPolicyProto.EVENTS, toState(mNewPolicy.allowEvents()));
+ proto.write(DNDPolicyProto.ALARMS, toState(mNewPolicy.allowAlarms()));
+ proto.write(DNDPolicyProto.MEDIA, toState(mNewPolicy.allowMedia()));
+ proto.write(DNDPolicyProto.SYSTEM, toState(mNewPolicy.allowSystem()));
+
+ proto.write(DNDPolicyProto.FULLSCREEN, toState(mNewPolicy.showFullScreenIntents()));
+ proto.write(DNDPolicyProto.LIGHTS, toState(mNewPolicy.showLights()));
+ proto.write(DNDPolicyProto.PEEK, toState(mNewPolicy.showPeeking()));
+ proto.write(DNDPolicyProto.STATUS_BAR, toState(mNewPolicy.showStatusBarIcons()));
+ proto.write(DNDPolicyProto.BADGE, toState(mNewPolicy.showBadges()));
+ proto.write(DNDPolicyProto.AMBIENT, toState(mNewPolicy.showAmbient()));
+ proto.write(DNDPolicyProto.NOTIFICATION_LIST,
+ toState(mNewPolicy.showInNotificationList()));
+
+ // Note: The DND policy proto uses the people type enum from *ZenPolicy* and not
+ // *NotificationManager.Policy* (which is the type of the consolidated policy).
+ // This applies to both call and message senders, but not conversation senders,
+ // where they use the same enum values.
+ proto.write(DNDPolicyProto.ALLOW_CALLS_FROM,
+ ZenModeConfig.getZenPolicySenders(mNewPolicy.allowCallsFrom()));
+ proto.write(DNDPolicyProto.ALLOW_MESSAGES_FROM,
+ ZenModeConfig.getZenPolicySenders(mNewPolicy.allowMessagesFrom()));
+ proto.write(DNDPolicyProto.ALLOW_CONVERSATIONS_FROM,
+ mNewPolicy.allowConversationsFrom());
+ } else {
+ Log.wtf(TAG, "attempted to write zen mode log event with null policy");
+ }
+
+ proto.flush();
+ return bytes.toByteArray();
+ }
+
+ /**
+ * Get whether any channels are bypassing DND based on the current new policy.
+ */
+ boolean getAreChannelsBypassing() {
+ if (mNewPolicy != null) {
+ return (mNewPolicy.state & STATE_CHANNELS_BYPASSING_DND) != 0;
+ }
+ return false;
+ }
+
+ private boolean hasChannelsBypassingDiff() {
+ boolean prevChannelsBypassing = mPrevPolicy != null
+ ? (mPrevPolicy.state & STATE_CHANNELS_BYPASSING_DND) != 0 : false;
+ return prevChannelsBypassing != getAreChannelsBypassing();
+ }
+
+ /**
+ * helper method to turn a boolean allow or disallow state into STATE_ALLOW or
+ * STATE_DISALLOW (there is no concept of "unset" in NM.Policy.)
+ */
+ private int toState(boolean allow) {
+ return allow ? ZenPolicy.STATE_ALLOW : ZenPolicy.STATE_DISALLOW;
+ }
+
+ /**
+ * Get the list of automatic rules that have any diff (as a List of ZenModeDiff.RuleDiff).
+ * Returns an empty list if there isn't anything.
+ */
+ private @NonNull ArrayMap<String, ZenModeDiff.RuleDiff> getChangedAutomaticRules() {
+ ArrayMap<String, ZenModeDiff.RuleDiff> ruleDiffs = new ArrayMap<>();
+
+ ZenModeDiff.ConfigDiff diff = new ZenModeDiff.ConfigDiff(mPrevConfig, mNewConfig);
+ if (!diff.hasDiff()) {
+ return ruleDiffs;
+ }
+
+ ArrayMap<String, ZenModeDiff.RuleDiff> autoDiffs = diff.getAllAutomaticRuleDiffs();
+ if (autoDiffs != null) {
+ return autoDiffs;
+ }
+ return ruleDiffs;
+ }
+
+ /**
+ * Get the package name associated with this rule's owner, given its id and associated
+ * RuleDiff, as well as the user ID associated with the config it was found in. Returns null
+ * if none could be found.
+ */
+ private Pair<String, Integer> getRulePackageAndUser(String id, ZenModeDiff.RuleDiff diff) {
+ // look for the rule info in the new config unless the rule was deleted.
+ ZenModeConfig configForSearch = mNewConfig;
+ if (diff.wasRemoved()) {
+ configForSearch = mPrevConfig;
+ }
+
+ if (configForSearch == null) {
+ return null;
+ }
+
+ ZenModeConfig.ZenRule rule = configForSearch.automaticRules.getOrDefault(id, null);
+ if (rule != null) {
+ if (rule.component != null) {
+ return new Pair(rule.component.getPackageName(), configForSearch.user);
+ }
+ if (rule.configurationActivity != null) {
+ return new Pair(rule.configurationActivity.getPackageName(),
+ configForSearch.user);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Get the package name listed as the manual rule "enabler", if it exists in the new config.
+ */
+ private String getNewManualRuleEnabler() {
+ if (mNewConfig == null || mNewConfig.manualRule == null) {
+ return null;
+ }
+ return mNewConfig.manualRule.enabler;
+ }
+
+ /**
+ * Makes a copy for storing intermediate state for testing purposes.
+ */
+ protected ZenStateChanges copy() {
+ ZenStateChanges copy = new ZenStateChanges();
+ copy.mPrevZenMode = mPrevZenMode;
+ copy.mNewZenMode = mNewZenMode;
+ copy.mPrevConfig = mPrevConfig.copy();
+ copy.mNewConfig = mNewConfig.copy();
+ copy.mPrevPolicy = mPrevPolicy.copy();
+ copy.mNewPolicy = mNewPolicy.copy();
+ copy.mCallingUid = mCallingUid;
+ copy.mFromSystemOrSystemUi = mFromSystemOrSystemUi;
+ return copy;
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index f38c6c1aa827..36a0b0c0d8e9 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -76,6 +76,7 @@ import android.util.proto.ProtoOutputStream;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.notification.SystemNotificationChannels;
@@ -125,6 +126,8 @@ public class ZenModeHelper {
@VisibleForTesting final SparseArray<ZenModeConfig> mConfigs = new SparseArray<>();
private final Metrics mMetrics = new Metrics();
private final ConditionProviders.Config mServiceConfig;
+ private SystemUiSystemPropertiesFlags.FlagResolver mFlagResolver;
+ @VisibleForTesting protected ZenModeEventLogger mZenModeEventLogger;
@VisibleForTesting protected int mZenMode;
@VisibleForTesting protected NotificationManager.Policy mConsolidatedPolicy;
@@ -144,7 +147,9 @@ public class ZenModeHelper {
private String[] mPriorityOnlyDndExemptPackages;
public ZenModeHelper(Context context, Looper looper, ConditionProviders conditionProviders,
- SysUiStatsEvent.BuilderFactory statsEventBuilderFactory) {
+ SysUiStatsEvent.BuilderFactory statsEventBuilderFactory,
+ SystemUiSystemPropertiesFlags.FlagResolver flagResolver,
+ ZenModeEventLogger zenModeEventLogger) {
mContext = context;
mHandler = new H(looper);
addCallback(mMetrics);
@@ -165,6 +170,8 @@ public class ZenModeHelper {
mConditions = new ZenModeConditions(this, conditionProviders);
mServiceConfig = conditionProviders.getConfig();
mStatsEventBuilderFactory = statsEventBuilderFactory;
+ mFlagResolver = flagResolver;
+ mZenModeEventLogger = zenModeEventLogger;
}
public Looper getLooper() {
@@ -214,7 +221,13 @@ public class ZenModeHelper {
public void initZenMode() {
if (DEBUG) Log.d(TAG, "initZenMode");
- evaluateZenMode("init", true /*setRingerMode*/);
+ synchronized (mConfig) {
+ // "update" config to itself, which will have no effect in the case where a config
+ // was read in via XML, but will initialize zen mode if nothing was read in and the
+ // config remains the default.
+ updateConfigAndZenModeLocked(mConfig, "init", true /*setRingerMode*/,
+ Process.SYSTEM_UID /* callingUid */, true /* is system */);
+ }
}
public void onSystemReady() {
@@ -266,7 +279,7 @@ public class ZenModeHelper {
config.user = user;
}
synchronized (mConfig) {
- setConfigLocked(config, null, reason);
+ setConfigLocked(config, null, reason, Process.SYSTEM_UID, true);
}
cleanUpZenRules();
}
@@ -275,11 +288,13 @@ public class ZenModeHelper {
return NotificationManager.zenModeToInterruptionFilter(mZenMode);
}
- public void requestFromListener(ComponentName name, int filter) {
+ public void requestFromListener(ComponentName name, int filter, int callingUid,
+ boolean fromSystemOrSystemUi) {
final int newZen = NotificationManager.zenModeFromInterruptionFilter(filter, -1);
if (newZen != -1) {
setManualZenMode(newZen, null, name != null ? name.getPackageName() : null,
- "listener:" + (name != null ? name.flattenToShortString() : null));
+ "listener:" + (name != null ? name.flattenToShortString() : null),
+ callingUid, fromSystemOrSystemUi);
}
}
@@ -324,7 +339,7 @@ public class ZenModeHelper {
}
public String addAutomaticZenRule(String pkg, AutomaticZenRule automaticZenRule,
- String reason) {
+ String reason, int callingUid, boolean fromSystemOrSystemUi) {
if (!ZenModeConfig.SYSTEM_AUTHORITY.equals(pkg)) {
PackageItemInfo component = getServiceInfo(automaticZenRule.getOwner());
if (component == null) {
@@ -360,7 +375,8 @@ public class ZenModeHelper {
ZenRule rule = new ZenRule();
populateZenRule(pkg, automaticZenRule, rule, true);
newConfig.automaticRules.put(rule.id, rule);
- if (setConfigLocked(newConfig, reason, rule.component, true)) {
+ if (setConfigLocked(newConfig, reason, rule.component, true, callingUid,
+ fromSystemOrSystemUi)) {
return rule.id;
} else {
throw new AndroidRuntimeException("Could not create rule");
@@ -369,7 +385,7 @@ public class ZenModeHelper {
}
public boolean updateAutomaticZenRule(String ruleId, AutomaticZenRule automaticZenRule,
- String reason) {
+ String reason, int callingUid, boolean fromSystemOrSystemUi) {
ZenModeConfig newConfig;
synchronized (mConfig) {
if (mConfig == null) return false;
@@ -395,11 +411,13 @@ public class ZenModeHelper {
}
populateZenRule(rule.pkg, automaticZenRule, rule, false);
- return setConfigLocked(newConfig, reason, rule.component, true);
+ return setConfigLocked(newConfig, reason, rule.component, true, callingUid,
+ fromSystemOrSystemUi);
}
}
- public boolean removeAutomaticZenRule(String id, String reason) {
+ public boolean removeAutomaticZenRule(String id, String reason, int callingUid,
+ boolean fromSystemOrSystemUi) {
ZenModeConfig newConfig;
synchronized (mConfig) {
if (mConfig == null) return false;
@@ -424,11 +442,13 @@ public class ZenModeHelper {
}
dispatchOnAutomaticRuleStatusChanged(
mConfig.user, ruleToRemove.getPkg(), id, AUTOMATIC_RULE_STATUS_REMOVED);
- return setConfigLocked(newConfig, reason, null, true);
+ return setConfigLocked(newConfig, reason, null, true, callingUid,
+ fromSystemOrSystemUi);
}
}
- public boolean removeAutomaticZenRules(String packageName, String reason) {
+ public boolean removeAutomaticZenRules(String packageName, String reason, int callingUid,
+ boolean fromSystemOrSystemUi) {
ZenModeConfig newConfig;
synchronized (mConfig) {
if (mConfig == null) return false;
@@ -439,11 +459,13 @@ public class ZenModeHelper {
newConfig.automaticRules.removeAt(i);
}
}
- return setConfigLocked(newConfig, reason, null, true);
+ return setConfigLocked(newConfig, reason, null, true, callingUid,
+ fromSystemOrSystemUi);
}
}
- public void setAutomaticZenRuleState(String id, Condition condition) {
+ public void setAutomaticZenRuleState(String id, Condition condition, int callingUid,
+ boolean fromSystemOrSystemUi) {
ZenModeConfig newConfig;
synchronized (mConfig) {
if (mConfig == null) return;
@@ -451,11 +473,13 @@ public class ZenModeHelper {
newConfig = mConfig.copy();
ArrayList<ZenRule> rules = new ArrayList<>();
rules.add(newConfig.automaticRules.get(id));
- setAutomaticZenRuleStateLocked(newConfig, rules, condition);
+ setAutomaticZenRuleStateLocked(newConfig, rules, condition, callingUid,
+ fromSystemOrSystemUi);
}
}
- public void setAutomaticZenRuleState(Uri ruleDefinition, Condition condition) {
+ public void setAutomaticZenRuleState(Uri ruleDefinition, Condition condition, int callingUid,
+ boolean fromSystemOrSystemUi) {
ZenModeConfig newConfig;
synchronized (mConfig) {
if (mConfig == null) return;
@@ -463,18 +487,19 @@ public class ZenModeHelper {
setAutomaticZenRuleStateLocked(newConfig,
findMatchingRules(newConfig, ruleDefinition, condition),
- condition);
+ condition, callingUid, fromSystemOrSystemUi);
}
}
private void setAutomaticZenRuleStateLocked(ZenModeConfig config, List<ZenRule> rules,
- Condition condition) {
+ Condition condition, int callingUid, boolean fromSystemOrSystemUi) {
if (rules == null || rules.isEmpty()) return;
for (ZenRule rule : rules) {
rule.condition = condition;
updateSnoozing(rule);
- setConfigLocked(config, rule.component, "conditionChanged");
+ setConfigLocked(config, rule.component, "conditionChanged", callingUid,
+ fromSystemOrSystemUi);
}
}
@@ -561,7 +586,7 @@ public class ZenModeHelper {
}
}
- protected void updateDefaultZenRules() {
+ protected void updateDefaultZenRules(int callingUid, boolean fromSystemOrSystemUi) {
updateDefaultAutomaticRuleNames();
for (ZenRule defaultRule : mDefaultConfig.automaticRules.values()) {
ZenRule currRule = mConfig.automaticRules.get(defaultRule.id);
@@ -575,7 +600,7 @@ public class ZenModeHelper {
// update default rule (if locale changed, name of rule will change)
currRule.name = defaultRule.name;
updateAutomaticZenRule(defaultRule.id, createAutomaticZenRule(currRule),
- "locale changed");
+ "locale changed", callingUid, fromSystemOrSystemUi);
}
}
}
@@ -650,14 +675,16 @@ public class ZenModeHelper {
return azr;
}
- public void setManualZenMode(int zenMode, Uri conditionId, String caller, String reason) {
- setManualZenMode(zenMode, conditionId, reason, caller, true /*setRingerMode*/);
+ public void setManualZenMode(int zenMode, Uri conditionId, String caller, String reason,
+ int callingUid, boolean fromSystemOrSystemUi) {
+ setManualZenMode(zenMode, conditionId, reason, caller, true /*setRingerMode*/, callingUid,
+ fromSystemOrSystemUi);
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.SHOW_ZEN_SETTINGS_SUGGESTION, 0);
}
private void setManualZenMode(int zenMode, Uri conditionId, String reason, String caller,
- boolean setRingerMode) {
+ boolean setRingerMode, int callingUid, boolean fromSystemOrSystemUi) {
ZenModeConfig newConfig;
synchronized (mConfig) {
if (mConfig == null) return;
@@ -681,7 +708,8 @@ public class ZenModeHelper {
newRule.enabler = caller;
newConfig.manualRule = newRule;
}
- setConfigLocked(newConfig, reason, null, setRingerMode);
+ setConfigLocked(newConfig, reason, null, setRingerMode, callingUid,
+ fromSystemOrSystemUi);
}
}
@@ -806,7 +834,7 @@ public class ZenModeHelper {
}
if (DEBUG) Log.d(TAG, reason);
synchronized (mConfig) {
- setConfigLocked(config, null, reason);
+ setConfigLocked(config, null, reason, Process.SYSTEM_UID, true);
}
}
}
@@ -838,12 +866,13 @@ public class ZenModeHelper {
/**
* Sets the global notification policy used for priority only do not disturb
*/
- public void setNotificationPolicy(Policy policy) {
+ public void setNotificationPolicy(Policy policy, int callingUid, boolean fromSystemOrSystemUi) {
if (policy == null || mConfig == null) return;
synchronized (mConfig) {
final ZenModeConfig newConfig = mConfig.copy();
newConfig.applyNotificationPolicy(policy);
- setConfigLocked(newConfig, null, "setNotificationPolicy");
+ setConfigLocked(newConfig, null, "setNotificationPolicy", callingUid,
+ fromSystemOrSystemUi);
}
}
@@ -868,7 +897,8 @@ public class ZenModeHelper {
}
}
}
- setConfigLocked(newConfig, null, "cleanUpZenRules");
+ setConfigLocked(newConfig, null, "cleanUpZenRules", Process.SYSTEM_UID,
+ true);
}
}
@@ -889,18 +919,21 @@ public class ZenModeHelper {
}
public boolean setConfigLocked(ZenModeConfig config, ComponentName triggeringComponent,
- String reason) {
- return setConfigLocked(config, reason, triggeringComponent, true /*setRingerMode*/);
+ String reason, int callingUid, boolean fromSystemOrSystemUi) {
+ return setConfigLocked(config, reason, triggeringComponent, true /*setRingerMode*/,
+ callingUid, fromSystemOrSystemUi);
}
- public void setConfig(ZenModeConfig config, ComponentName triggeringComponent, String reason) {
+ public void setConfig(ZenModeConfig config, ComponentName triggeringComponent, String reason,
+ int callingUid, boolean fromSystemOrSystemUi) {
synchronized (mConfig) {
- setConfigLocked(config, triggeringComponent, reason);
+ setConfigLocked(config, triggeringComponent, reason, callingUid, fromSystemOrSystemUi);
}
}
private boolean setConfigLocked(ZenModeConfig config, String reason,
- ComponentName triggeringComponent, boolean setRingerMode) {
+ ComponentName triggeringComponent, boolean setRingerMode, int callingUid,
+ boolean fromSystemOrSystemUi) {
final long identity = Binder.clearCallingIdentity();
try {
if (config == null || !config.isValid()) {
@@ -927,17 +960,11 @@ public class ZenModeHelper {
// send some broadcasts
final boolean policyChanged = !Objects.equals(getNotificationPolicy(mConfig),
getNotificationPolicy(config));
- if (!config.equals(mConfig)) {
- mConfig = config;
- dispatchOnConfigChanged();
- updateConsolidatedPolicy(reason);
- }
if (policyChanged) {
dispatchOnPolicyChanged();
}
- final String val = Integer.toString(config.hashCode());
- Global.putString(mContext.getContentResolver(), Global.ZEN_MODE_CONFIG_ETAG, val);
- evaluateZenMode(reason, setRingerMode);
+ updateConfigAndZenModeLocked(config, reason, setRingerMode, callingUid,
+ fromSystemOrSystemUi);
mConditions.evaluateConfig(config, triggeringComponent, true /*processSubscriptions*/);
return true;
} catch (SecurityException e) {
@@ -948,6 +975,34 @@ public class ZenModeHelper {
}
}
+ /**
+ * Carries out a config update (if needed) and (re-)evaluates the zen mode value afterwards.
+ * If logging is enabled, will also request logging of the outcome of this change if needed.
+ */
+ private void updateConfigAndZenModeLocked(ZenModeConfig config, String reason,
+ boolean setRingerMode, int callingUid, boolean fromSystemOrSystemUi) {
+ final boolean logZenModeEvents = mFlagResolver.isEnabled(
+ SystemUiSystemPropertiesFlags.NotificationFlags.LOG_DND_STATE_EVENTS);
+ // Store (a copy of) all config and zen mode info prior to any changes taking effect
+ ZenModeEventLogger.ZenModeInfo prevInfo = new ZenModeEventLogger.ZenModeInfo(
+ mZenMode, mConfig, mConsolidatedPolicy);
+ if (!config.equals(mConfig)) {
+ mConfig = config;
+ dispatchOnConfigChanged();
+ updateConsolidatedPolicy(reason);
+ }
+ final String val = Integer.toString(config.hashCode());
+ Global.putString(mContext.getContentResolver(), Global.ZEN_MODE_CONFIG_ETAG, val);
+ evaluateZenMode(reason, setRingerMode);
+ // After all changes have occurred, log if requested
+ if (logZenModeEvents) {
+ ZenModeEventLogger.ZenModeInfo newInfo = new ZenModeEventLogger.ZenModeInfo(
+ mZenMode, mConfig, mConsolidatedPolicy);
+ mZenModeEventLogger.maybeLogZenChange(prevInfo, newInfo, callingUid,
+ fromSystemOrSystemUi);
+ }
+ }
+
private int getZenModeSetting() {
return Global.getInt(mContext.getContentResolver(), Global.ZEN_MODE, Global.ZEN_MODE_OFF);
}
@@ -1366,7 +1421,7 @@ public class ZenModeHelper {
if (newZen != -1) {
setManualZenMode(newZen, null, "ringerModeInternal", null,
- false /*setRingerMode*/);
+ false /*setRingerMode*/, Process.SYSTEM_UID, true);
}
if (isChange || newZen != -1 || ringerModeExternal != ringerModeExternalOut) {
ZenLog.traceSetRingerModeInternal(ringerModeOld, ringerModeNew, caller,
@@ -1404,7 +1459,7 @@ public class ZenModeHelper {
}
if (newZen != -1) {
setManualZenMode(newZen, null, "ringerModeExternal", caller,
- false /*setRingerMode*/);
+ false /*setRingerMode*/, Process.SYSTEM_UID, true);
}
ZenLog.traceSetRingerModeExternal(ringerModeOld, ringerModeNew, caller,
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index ff6c534b81ed..8218d5905a13 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -2192,6 +2192,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
any(), anyString(), anyInt(), anyString(), anyInt()))
.thenReturn(SHOW_IMMEDIATELY);
mService.isSystemUid = false;
+ mService.isSystemAppId = false;
final NotificationRecord parent = generateNotificationRecord(
mTestNotificationChannel, 1, "group", true);
final NotificationRecord child = generateNotificationRecord(
@@ -2218,6 +2219,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
any(), anyString(), anyInt(), anyString(), anyInt()))
.thenReturn(SHOW_IMMEDIATELY);
mService.isSystemUid = false;
+ mService.isSystemAppId = false;
final NotificationRecord parent = generateNotificationRecord(
mTestNotificationChannel, 1, "group", true);
parent.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
@@ -2241,6 +2243,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
public void testCancelNotificationWithTag_fromApp_canCancelOngoingNoClearChild()
throws Exception {
mService.isSystemUid = false;
+ mService.isSystemAppId = false;
final NotificationRecord parent = generateNotificationRecord(
mTestNotificationChannel, 1, "group", true);
final NotificationRecord child = generateNotificationRecord(
@@ -2264,6 +2267,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
public void testCancelNotificationWithTag_fromApp_canCancelOngoingNoClearParent()
throws Exception {
mService.isSystemUid = false;
+ mService.isSystemAppId = false;
final NotificationRecord parent = generateNotificationRecord(
mTestNotificationChannel, 1, "group", true);
parent.getNotification().flags |= FLAG_ONGOING_EVENT | FLAG_NO_CLEAR;
@@ -2290,6 +2294,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
any(), anyString(), anyInt(), anyString(), anyInt()))
.thenReturn(SHOW_IMMEDIATELY);
mService.isSystemUid = false;
+ mService.isSystemAppId = false;
final NotificationRecord parent = generateNotificationRecord(
mTestNotificationChannel, 1, "group", true);
final NotificationRecord child = generateNotificationRecord(
@@ -2318,6 +2323,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
any(), anyString(), anyInt(), anyString(), anyInt()))
.thenReturn(SHOW_IMMEDIATELY);
mService.isSystemUid = false;
+ mService.isSystemAppId = false;
final NotificationRecord parent = generateNotificationRecord(
mTestNotificationChannel, 1, "group", true);
parent.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
@@ -2343,6 +2349,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
public void testCancelAllNotifications_fromApp_canCancelOngoingNoClearChild()
throws Exception {
mService.isSystemUid = false;
+ mService.isSystemAppId = false;
final NotificationRecord parent = generateNotificationRecord(
mTestNotificationChannel, 1, "group", true);
final NotificationRecord child = generateNotificationRecord(
@@ -2368,6 +2375,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
public void testCancelAllNotifications_fromApp_canCancelOngoingNoClearParent()
throws Exception {
mService.isSystemUid = false;
+ mService.isSystemAppId = false;
final NotificationRecord parent = generateNotificationRecord(
mTestNotificationChannel, 1, "group", true);
parent.getNotification().flags |= FLAG_ONGOING_EVENT | FLAG_NO_CLEAR;
@@ -3207,7 +3215,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
eq(channel2.getId()), anyBoolean()))
.thenReturn(channel2);
when(mPreferencesHelper.createNotificationChannel(eq(PKG), anyInt(),
- eq(channel2), anyBoolean(), anyBoolean()))
+ eq(channel2), anyBoolean(), anyBoolean(), anyInt(), anyBoolean()))
.thenReturn(true);
reset(mListeners);
@@ -3266,7 +3274,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
eq(mTestNotificationChannel.getId()), anyBoolean()))
.thenReturn(mTestNotificationChannel);
when(mPreferencesHelper.deleteNotificationChannel(eq(PKG), anyInt(),
- eq(mTestNotificationChannel.getId()))).thenReturn(true);
+ eq(mTestNotificationChannel.getId()), anyInt(), anyBoolean())).thenReturn(true);
reset(mListeners);
mBinderService.deleteNotificationChannel(PKG, mTestNotificationChannel.getId());
verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
@@ -3365,7 +3373,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
null, PKG, Process.myUserHandle(), mTestNotificationChannel);
verify(mPreferencesHelper, times(1)).updateNotificationChannel(
- anyString(), anyInt(), any(), anyBoolean());
+ anyString(), anyInt(), any(), anyBoolean(), anyInt(), anyBoolean());
verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG),
eq(Process.myUserHandle()), eq(mTestNotificationChannel),
@@ -3387,7 +3395,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
verify(mPreferencesHelper, never()).updateNotificationChannel(
- anyString(), anyInt(), any(), anyBoolean());
+ anyString(), anyInt(), any(), anyBoolean(), anyInt(), anyBoolean());
verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG),
eq(Process.myUserHandle()), eq(mTestNotificationChannel),
@@ -3413,7 +3421,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
verify(mPreferencesHelper, never()).updateNotificationChannel(
- anyString(), anyInt(), any(), anyBoolean());
+ anyString(), anyInt(), any(), anyBoolean(), anyInt(), anyBoolean());
verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG),
eq(Process.myUserHandle()), eq(mTestNotificationChannel),
@@ -4893,7 +4901,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
mService.mLocaleChangeReceiver.onReceive(mContext,
new Intent(Intent.ACTION_LOCALE_CHANGED));
- verify(mZenModeHelper, times(1)).updateDefaultZenRules();
+ verify(mZenModeHelper, times(1)).updateDefaultZenRules(
+ anyInt(), anyBoolean());
}
@Test
@@ -6710,6 +6719,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
final String testPackage = "testPackageName";
assertEquals(0, mService.mToastQueue.size());
mService.isSystemUid = false;
+ mService.isSystemAppId = false;
setToastRateIsWithinQuota(true);
setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
@@ -6732,6 +6742,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
final String testPackage = "testPackageName";
assertEquals(0, mService.mToastQueue.size());
mService.isSystemUid = false;
+ mService.isSystemAppId = false;
setToastRateIsWithinQuota(true);
setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
@@ -6751,6 +6762,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
final String testPackage = "testPackageName";
assertEquals(0, mService.mToastQueue.size());
mService.isSystemUid = false;
+ mService.isSystemAppId = false;
setToastRateIsWithinQuota(true);
setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
@@ -6780,6 +6792,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
final String testPackage = "testPackageName";
assertEquals(0, mService.mToastQueue.size());
mService.isSystemUid = false;
+ mService.isSystemAppId = false;
setToastRateIsWithinQuota(false); // rate limit reached
setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
@@ -6803,6 +6816,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
final String testPackage = "testPackageName";
assertEquals(0, mService.mToastQueue.size());
mService.isSystemUid = false;
+ mService.isSystemAppId = false;
setToastRateIsWithinQuota(true);
setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
@@ -6837,6 +6851,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
final String testPackage = "testPackageName";
assertEquals(0, mService.mToastQueue.size());
mService.isSystemUid = false;
+ mService.isSystemAppId = false;
setToastRateIsWithinQuota(true);
setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
@@ -6856,6 +6871,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
final String testPackage = "testPackageName";
assertEquals(0, mService.mToastQueue.size());
mService.isSystemUid = false;
+ mService.isSystemAppId = false;
setToastRateIsWithinQuota(true);
setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
@@ -6875,6 +6891,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
final String testPackage = "testPackageName";
assertEquals(0, mService.mToastQueue.size());
mService.isSystemUid = false;
+ mService.isSystemAppId = false;
setToastRateIsWithinQuota(true);
setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
@@ -6905,6 +6922,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
final String testPackage = "testPackageName";
assertEquals(0, mService.mToastQueue.size());
mService.isSystemUid = false;
+ mService.isSystemAppId = false;
setToastRateIsWithinQuota(false); // rate limit reached
setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
setAppInForegroundForToasts(mUid, false);
@@ -6927,6 +6945,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
final String testPackage = "testPackageName";
assertEquals(0, mService.mToastQueue.size());
mService.isSystemUid = false;
+ mService.isSystemAppId = false;
setToastRateIsWithinQuota(false); // rate limit reached
setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
setAppInForegroundForToasts(mUid, true);
@@ -6948,6 +6967,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
final String testPackage = "testPackageName";
assertEquals(0, mService.mToastQueue.size());
mService.isSystemUid = false;
+ mService.isSystemAppId = false;
setToastRateIsWithinQuota(false); // rate limit reached
setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, true);
setAppInForegroundForToasts(mUid, false);
@@ -6969,6 +6989,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
final String testPackage = "testPackageName";
assertEquals(0, mService.mToastQueue.size());
mService.isSystemUid = false;
+ mService.isSystemAppId = false;
setToastRateIsWithinQuota(false); // rate limit reached
setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
setAppInForegroundForToasts(mUid, false);
@@ -7027,6 +7048,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
final String testPackage = "testPackageName";
assertEquals(0, mService.mToastQueue.size());
mService.isSystemUid = false;
+ mService.isSystemAppId = false;
setToastRateIsWithinQuota(true);
setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
@@ -7048,6 +7070,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
final String testPackage = "testPackageName";
assertEquals(0, mService.mToastQueue.size());
mService.isSystemUid = false;
+ mService.isSystemAppId = false;
setToastRateIsWithinQuota(true);
setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
@@ -7151,6 +7174,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
final String testPackage = "testPackageName";
assertEquals(0, mService.mToastQueue.size());
mService.isSystemUid = false;
+ mService.isSystemAppId = false;
setToastRateIsWithinQuota(true);
setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
mockIsUserVisible(DEFAULT_DISPLAY, false);
@@ -7171,6 +7195,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
final String testPackage = "testPackageName";
assertEquals(0, mService.mToastQueue.size());
mService.isSystemUid = false;
+ mService.isSystemAppId = false;
setToastRateIsWithinQuota(true);
setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
@@ -7193,6 +7218,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
final String testPackage = "testPackageName";
assertEquals(0, mService.mToastQueue.size());
mService.isSystemUid = false;
+ mService.isSystemAppId = false;
setToastRateIsWithinQuota(true);
setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
@@ -7237,6 +7263,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
final String testPackage = "testPackageName";
assertEquals(0, mService.mToastQueue.size());
mService.isSystemUid = false;
+ mService.isSystemAppId = false;
setToastRateIsWithinQuota(true);
setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
@@ -8128,7 +8155,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
mBinderService.addAutomaticZenRule(rule, "com.android.settings");
// verify that zen mode helper gets passed in a package name of "android"
- verify(mockZenModeHelper).addAutomaticZenRule(eq("android"), eq(rule), anyString());
+ verify(mockZenModeHelper).addAutomaticZenRule(eq("android"), eq(rule), anyString(),
+ anyInt(), eq(true)); // system call counts as "is system or system ui"
}
@Test
@@ -8149,7 +8177,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
mBinderService.addAutomaticZenRule(rule, "com.android.settings");
// verify that zen mode helper gets passed in a package name of "android"
- verify(mockZenModeHelper).addAutomaticZenRule(eq("android"), eq(rule), anyString());
+ verify(mockZenModeHelper).addAutomaticZenRule(eq("android"), eq(rule), anyString(),
+ anyInt(), eq(true)); // system call counts as "system or system ui"
}
@Test
@@ -8169,7 +8198,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
// verify that zen mode helper gets passed in the package name from the arg, not the owner
verify(mockZenModeHelper).addAutomaticZenRule(
- eq("another.package"), eq(rule), anyString());
+ eq("another.package"), eq(rule), anyString(), anyInt(),
+ eq(false)); // doesn't count as a system/systemui call
}
@Test
@@ -9988,8 +10018,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
@Test
public void testMatchesCallFilter_noPermissionShouldThrow() throws Exception {
- // set the testable NMS to not system uid
+ // set the testable NMS to not system uid/appid
mService.isSystemUid = false;
+ mService.isSystemAppId = false;
// make sure a caller without listener access or read_contacts permission can't call
// matchesCallFilter.
@@ -10028,6 +10059,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
@Test
public void testMatchesCallFilter_hasListenerPermission() throws Exception {
mService.isSystemUid = false;
+ mService.isSystemAppId = false;
// make sure a caller with only listener access and not read_contacts permission can call
// matchesCallFilter.
@@ -10046,6 +10078,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
@Test
public void testMatchesCallFilter_hasContactsPermission() throws Exception {
mService.isSystemUid = false;
+ mService.isSystemAppId = false;
// make sure a caller with only read_contacts permission and not listener access can call
// matchesCallFilter.
@@ -11176,6 +11209,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
when(mJsi.isNotificationAssociatedWithAnyUserInitiatedJobs(anyInt(), anyInt(), anyString()))
.thenReturn(true);
mService.isSystemUid = false;
+ mService.isSystemAppId = false;
final NotificationRecord parent = generateNotificationRecord(
mTestNotificationChannel, 1, "group", true);
final NotificationRecord child = generateNotificationRecord(
@@ -11200,6 +11234,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
when(mJsi.isNotificationAssociatedWithAnyUserInitiatedJobs(anyInt(), anyInt(), anyString()))
.thenReturn(true);
mService.isSystemUid = false;
+ mService.isSystemAppId = false;
final NotificationRecord parent = generateNotificationRecord(
mTestNotificationChannel, 1, "group", true);
parent.getNotification().flags |= FLAG_USER_INITIATED_JOB;
@@ -11224,6 +11259,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
when(mJsi.isNotificationAssociatedWithAnyUserInitiatedJobs(anyInt(), anyInt(), anyString()))
.thenReturn(true);
mService.isSystemUid = false;
+ mService.isSystemAppId = false;
final NotificationRecord parent = generateNotificationRecord(
mTestNotificationChannel, 1, "group", true);
final NotificationRecord child = generateNotificationRecord(
@@ -11250,6 +11286,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
when(mJsi.isNotificationAssociatedWithAnyUserInitiatedJobs(anyInt(), anyInt(), anyString()))
.thenReturn(true);
mService.isSystemUid = false;
+ mService.isSystemAppId = false;
final NotificationRecord parent = generateNotificationRecord(
mTestNotificationChannel, 1, "group", true);
parent.getNotification().flags |= FLAG_USER_INITIATED_JOB;
@@ -11673,6 +11710,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
private void allowTestPackageToToast() throws Exception {
assertWithMessage("toast queue").that(mService.mToastQueue).isEmpty();
mService.isSystemUid = false;
+ mService.isSystemAppId = false;
setToastRateIsWithinQuota(true);
setIfPackageHasPermissionToAvoidToastRateLimiting(TEST_PACKAGE, false);
// package is not suspended
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index c78b03e4b5cb..48ad86da1bc5 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -60,6 +60,7 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
@@ -421,13 +422,15 @@ public class PreferencesHelperTest extends UiServiceTestCase {
int uid0 = 1001;
setUpPackageWithUid(package0, uid0);
NotificationChannel channel0 = new NotificationChannel("id0", "name0", IMPORTANCE_HIGH);
- assertTrue(mHelper.createNotificationChannel(package0, uid0, channel0, true, false));
+ assertTrue(mHelper.createNotificationChannel(package0, uid0, channel0, true, false,
+ uid0, false));
String package10 = "test.package.user10";
int uid10 = 1001001;
setUpPackageWithUid(package10, uid10);
NotificationChannel channel10 = new NotificationChannel("id10", "name10", IMPORTANCE_HIGH);
- assertTrue(mHelper.createNotificationChannel(package10, uid10, channel10, true, false));
+ assertTrue(mHelper.createNotificationChannel(package10, uid10, channel10, true, false,
+ uid10, false));
ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> appPermissions = new ArrayMap<>();
appPermissions.put(new Pair<>(uid0, package0), new Pair<>(false, false));
@@ -459,7 +462,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
int uid0 = 1001;
setUpPackageWithUid(package0, uid0);
NotificationChannel channel0 = new NotificationChannel("id0", "name0", IMPORTANCE_HIGH);
- assertTrue(mHelper.createNotificationChannel(package0, uid0, channel0, true, false));
+ assertTrue(mHelper.createNotificationChannel(package0, uid0, channel0, true, false,
+ uid0, false));
ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> appPermissions = new ArrayMap<>();
appPermissions.put(new Pair<>(uid0, package0), new Pair<>(true, false));
@@ -506,10 +510,14 @@ public class PreferencesHelperTest extends UiServiceTestCase {
channel2.setConversationId("id1", "conversation");
channel2.setDemoted(true);
- mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
- mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
- assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false));
- assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false));
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true,
+ UID_N_MR1, false);
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true,
+ UID_N_MR1, false);
+ assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false,
+ UID_N_MR1, false));
+ assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false,
+ UID_N_MR1, false));
mHelper.setShowBadge(PKG_N_MR1, UID_N_MR1, true);
@@ -569,12 +577,18 @@ public class PreferencesHelperTest extends UiServiceTestCase {
NotificationChannel channel3 = new NotificationChannel("id3", "NAM3", IMPORTANCE_HIGH);
channel3.enableVibration(true);
- mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
- mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, false, false);
- mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false);
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true,
+ UID_N_MR1, false);
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true,
+ UID_N_MR1, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false,
+ UID_N_MR1, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false,
+ SYSTEM_UID, true);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, false, false,
+ SYSTEM_UID, true);
+ mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false,
+ UID_N_MR1, false);
mHelper.setShowBadge(PKG_N_MR1, UID_N_MR1, true);
mHelper.setInvalidMessageSent(PKG_P, UID_P);
@@ -1040,12 +1054,18 @@ public class PreferencesHelperTest extends UiServiceTestCase {
NotificationChannel channel3 = new NotificationChannel("id3", "NAM3", IMPORTANCE_HIGH);
channel3.enableVibration(true);
- mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
- mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, false, false);
- mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false);
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true,
+ UID_N_MR1, false);
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true,
+ UID_N_MR1, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false,
+ UID_N_MR1, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false,
+ SYSTEM_UID, true);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, false, false,
+ SYSTEM_UID, true);
+ mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false,
+ UID_N_MR1, false);
mHelper.setShowBadge(PKG_N_MR1, UID_N_MR1, true);
mHelper.setInvalidMessageSent(PKG_P, UID_P);
@@ -1120,12 +1140,18 @@ public class PreferencesHelperTest extends UiServiceTestCase {
NotificationChannel channel3 = new NotificationChannel("id3", "NAM3", IMPORTANCE_HIGH);
channel3.enableVibration(true);
- mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
- mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, false, false);
- mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false);
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true,
+ UID_N_MR1, false);
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true,
+ UID_N_MR1, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false,
+ UID_N_MR1, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false,
+ SYSTEM_UID, true);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, false, false,
+ SYSTEM_UID, true);
+ mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false,
+ UID_N_MR1, false);
mHelper.setShowBadge(PKG_N_MR1, UID_N_MR1, true);
mHelper.setInvalidMessageSent(PKG_P, UID_P);
@@ -1202,12 +1228,18 @@ public class PreferencesHelperTest extends UiServiceTestCase {
NotificationChannel channel3 = new NotificationChannel("id3", "NAM3", IMPORTANCE_HIGH);
channel3.enableVibration(true);
- mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
- mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, false, false);
- mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false);
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true,
+ UID_N_MR1, false);
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true,
+ UID_N_MR1, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false,
+ UID_N_MR1, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false,
+ SYSTEM_UID, true);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, false, false,
+ SYSTEM_UID, true);
+ mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false,
+ UID_N_MR1, false);
mHelper.setShowBadge(PKG_N_MR1, UID_N_MR1, true);
mHelper.setInvalidMessageSent(PKG_P, UID_P);
@@ -1285,7 +1317,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
NotificationChannel channel =
new NotificationChannel("id", "name", IMPORTANCE_LOW);
channel.setSound(SOUND_URI, mAudioAttributes);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false,
+ UID_N_MR1, false);
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
USER_SYSTEM, channel.getId());
@@ -1312,7 +1345,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
NotificationChannel channel =
new NotificationChannel("id", "name", IMPORTANCE_LOW);
channel.setSound(SOUND_URI, mAudioAttributes);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false,
+ UID_N_MR1, false);
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
USER_SYSTEM, channel.getId());
@@ -1334,7 +1368,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
NotificationChannel channel =
new NotificationChannel("id", "name", IMPORTANCE_LOW);
channel.setSound(SOUND_URI, mAudioAttributes);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false,
+ UID_N_MR1, false);
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
USER_SYSTEM, channel.getId());
@@ -1359,7 +1394,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
NotificationChannel channel =
new NotificationChannel("id", "name", IMPORTANCE_LOW);
channel.setSound(SOUND_URI, mAudioAttributes);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false,
+ UID_N_MR1, false);
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
USER_SYSTEM, channel.getId());
@@ -1437,7 +1473,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
NotificationChannel channel =
new NotificationChannel("id", "name", IMPORTANCE_LOW);
channel.setSound(null, mAudioAttributes);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false,
+ UID_N_MR1, false);
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
USER_SYSTEM, channel.getId());
@@ -1466,7 +1503,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
NotificationChannel channel =
new NotificationChannel("id", "name", IMPORTANCE_LOW);
channel.setSound(ANDROID_RES_SOUND_URI, mAudioAttributes);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false,
+ UID_N_MR1, false);
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
USER_SYSTEM, channel.getId());
@@ -1501,7 +1539,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
NotificationChannel channel =
new NotificationChannel("id", "name", IMPORTANCE_LOW);
channel.setSound(FILE_SOUND_URI, mAudioAttributes);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false,
+ UID_N_MR1, false);
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
USER_SYSTEM, channel.getId());
@@ -1527,14 +1566,21 @@ public class PreferencesHelperTest extends UiServiceTestCase {
new NotificationChannel("id3", "name3", IMPORTANCE_LOW);
channel3.setGroup(ncg.getId());
- mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
- mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, true, false);
-
- mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1.getId());
- mHelper.deleteNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg.getId());
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true,
+ UID_N_MR1, false);
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true,
+ UID_N_MR1, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false,
+ UID_N_MR1, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false,
+ SYSTEM_UID, true);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, true, false,
+ UID_N_MR1, false);
+
+ mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1.getId(),
+ UID_N_MR1, false);
+ mHelper.deleteNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg.getId(),
+ UID_N_MR1, false);
assertEquals(channel2,
mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2.getId(), false));
@@ -1578,7 +1624,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
UID_N_MR1,
NotificationChannel.DEFAULT_CHANNEL_ID, false);
defaultChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
- mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, defaultChannel, true);
+ mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, defaultChannel, true,
+ UID_N_MR1, false);
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
UserHandle.USER_ALL, NotificationChannel.DEFAULT_CHANNEL_ID);
@@ -1641,7 +1688,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
@Test
public void testDeletesDefaultChannelAfterChannelIsCreated() throws Exception {
mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
- new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false);
+ new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false,
+ UID_N_MR1, false);
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
UserHandle.USER_ALL, NotificationChannel.DEFAULT_CHANNEL_ID, "bananas");
@@ -1661,7 +1709,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
UserHandle.USER_ALL, NotificationChannel.DEFAULT_CHANNEL_ID, "bananas");
mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
- new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false);
+ new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false,
+ UID_N_MR1, false);
loadStreamXml(baos, false, UserHandle.USER_ALL);
@@ -1674,7 +1723,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
try {
mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
new NotificationChannel("bananas", "bananas", IMPORTANCE_NONE - 1),
- true, false);
+ true, false, UID_N_MR1, false);
fail("Was allowed to create a channel with invalid importance");
} catch (IllegalArgumentException e) {
// yay
@@ -1682,7 +1731,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
try {
mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
new NotificationChannel("bananas", "bananas", IMPORTANCE_UNSPECIFIED),
- true, false);
+ true, false, UID_N_MR1, false);
fail("Was allowed to create a channel with invalid importance");
} catch (IllegalArgumentException e) {
// yay
@@ -1690,57 +1739,61 @@ public class PreferencesHelperTest extends UiServiceTestCase {
try {
mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
new NotificationChannel("bananas", "bananas", IMPORTANCE_MAX + 1),
- true, false);
+ true, false, UID_N_MR1, false);
fail("Was allowed to create a channel with invalid importance");
} catch (IllegalArgumentException e) {
// yay
}
assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
- new NotificationChannel("bananas", "bananas", IMPORTANCE_NONE), true, false));
+ new NotificationChannel("bananas", "bananas", IMPORTANCE_NONE), true, false,
+ UID_N_MR1, false));
assertFalse(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
- new NotificationChannel("bananas", "bananas", IMPORTANCE_MAX), true, false));
+ new NotificationChannel("bananas", "bananas", IMPORTANCE_MAX), true, false,
+ UID_N_MR1, false));
}
@Test
public void testUpdateChannel_downgradeImportance() {
mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
new NotificationChannel("bananas", "bananas", IMPORTANCE_DEFAULT),
- true, false);
+ true, false, UID_N_MR1, false);
assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
- new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false));
+ new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false,
+ UID_N_MR1, false));
}
@Test
public void testUpdateChannel_upgradeImportance_ignored() {
mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
new NotificationChannel("bananas", "bananas", IMPORTANCE_DEFAULT),
- true, false);
+ true, false, UID_N_MR1, false);
assertFalse(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
- new NotificationChannel("bananas", "bananas", IMPORTANCE_MAX), true, false));
+ new NotificationChannel("bananas", "bananas", IMPORTANCE_MAX), true, false,
+ UID_N_MR1, false));
}
@Test
public void testUpdateChannel_badImportance() {
mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
new NotificationChannel("bananas", "bananas", IMPORTANCE_DEFAULT),
- true, false);
+ true, false, UID_N_MR1, false);
assertThrows(IllegalArgumentException.class,
() -> mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
new NotificationChannel("bananas", "bananas", IMPORTANCE_NONE - 1), true,
- false));
+ false, UID_N_MR1, false));
assertThrows(IllegalArgumentException.class,
() -> mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
new NotificationChannel("bananas", "bananas", IMPORTANCE_UNSPECIFIED), true,
- false));
+ false, UID_N_MR1, false));
assertThrows(IllegalArgumentException.class,
() -> mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
new NotificationChannel("bananas", "bananas", IMPORTANCE_MAX + 1), true,
- false));
+ false, UID_N_MR1, false));
}
@Test
@@ -1753,7 +1806,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
channel.setBypassDnd(true);
channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
- assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, false, false));
+ assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, false, false,
+ SYSTEM_UID, true));
// same id, try to update all fields
final NotificationChannel channel2 =
@@ -1763,7 +1817,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
channel2.setBypassDnd(false);
channel2.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
- mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true);
+ mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true,
+ SYSTEM_UID, true);
// all fields should be changed
assertEquals(channel2,
@@ -1788,7 +1843,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
defaultChannel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
mHelper.setAppImportanceLocked(PKG_N_MR1, UID_N_MR1);
- mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, defaultChannel, true);
+ mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, defaultChannel, true,
+ SYSTEM_UID, true);
// ensure app level fields are changed
assertFalse(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
@@ -1801,7 +1857,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
public void testUpdate_postUpgrade_noUpdateAppFields() throws Exception {
final NotificationChannel channel = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
- mHelper.createNotificationChannel(PKG_O, UID_O, channel, false, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, channel, false, false,
+ SYSTEM_UID, true);
assertTrue(mHelper.canShowBadge(PKG_O, UID_O));
assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_O, UID_O));
assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
@@ -1812,7 +1869,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
channel.setBypassDnd(true);
channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
- mHelper.updateNotificationChannel(PKG_O, UID_O, channel, true);
+ mHelper.updateNotificationChannel(PKG_O, UID_O, channel, true,
+ SYSTEM_UID, true);
// ensure app level fields are not changed
assertTrue(mHelper.canShowBadge(PKG_O, UID_O));
@@ -1825,7 +1883,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
public void testUpdate_preUpgrade_noUpdateAppFieldsWithMultipleChannels() throws Exception {
final NotificationChannel channel = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, false, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, false, false,
+ SYSTEM_UID, true);
assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_N_MR1, UID_N_MR1));
assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
@@ -1836,7 +1895,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
channel.setBypassDnd(true);
channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
- mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true);
+ mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true,
+ SYSTEM_UID, true);
NotificationChannel defaultChannel = mHelper.getNotificationChannel(
PKG_N_MR1, UID_N_MR1, NotificationChannel.DEFAULT_CHANNEL_ID, false);
@@ -1846,7 +1906,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
defaultChannel.setBypassDnd(true);
defaultChannel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
- mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, defaultChannel, true);
+ mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, defaultChannel, true,
+ SYSTEM_UID, true);
// ensure app level fields are not changed
assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
@@ -1877,7 +1938,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
}
channel.lockFields(lockMask);
- assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false));
+ assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false,
+ UID_N_MR1, false));
NotificationChannel savedChannel =
mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(), false);
@@ -1909,7 +1971,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
}
channel.lockFields(lockMask);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false,
+ UID_N_MR1, false);
NotificationChannel savedChannel =
mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(), false);
@@ -1936,13 +1999,14 @@ public class PreferencesHelperTest extends UiServiceTestCase {
@Test
public void testLockFields_soundAndVibration() {
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false,
+ UID_N_MR1, false);
final NotificationChannel update1 = getChannel();
update1.setSound(new Uri.Builder().scheme("test").build(),
new AudioAttributes.Builder().build());
update1.lockFields(NotificationChannel.USER_LOCKED_PRIORITY);
- mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update1, true);
+ mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update1, true, SYSTEM_UID, true);
assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
| NotificationChannel.USER_LOCKED_SOUND,
mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update1.getId(), false)
@@ -1950,7 +2014,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
NotificationChannel update2 = getChannel();
update2.enableVibration(true);
- mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update2, true);
+ mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update2, true, SYSTEM_UID, true);
assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
| NotificationChannel.USER_LOCKED_SOUND
| NotificationChannel.USER_LOCKED_VIBRATION,
@@ -1960,18 +2024,19 @@ public class PreferencesHelperTest extends UiServiceTestCase {
@Test
public void testLockFields_vibrationAndLights() {
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false,
+ SYSTEM_UID, true);
final NotificationChannel update1 = getChannel();
update1.setVibrationPattern(new long[]{7945, 46 ,246});
- mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update1, true);
+ mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update1, true, SYSTEM_UID, true);
assertEquals(NotificationChannel.USER_LOCKED_VIBRATION,
mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update1.getId(), false)
.getUserLockedFields());
final NotificationChannel update2 = getChannel();
update2.enableLights(true);
- mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update2, true);
+ mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update2, true, SYSTEM_UID, true);
assertEquals(NotificationChannel.USER_LOCKED_VIBRATION
| NotificationChannel.USER_LOCKED_LIGHTS,
mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update2.getId(), false)
@@ -1980,18 +2045,20 @@ public class PreferencesHelperTest extends UiServiceTestCase {
@Test
public void testLockFields_lightsAndImportance() {
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false,
+ UID_N_MR1, false);
final NotificationChannel update1 = getChannel();
update1.setLightColor(Color.GREEN);
- mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update1, true);
+ mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update1, true, SYSTEM_UID, true);
assertEquals(NotificationChannel.USER_LOCKED_LIGHTS,
mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update1.getId(), false)
.getUserLockedFields());
final NotificationChannel update2 = getChannel();
update2.setImportance(IMPORTANCE_DEFAULT);
- mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update2, true);
+ mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update2, true,
+ SYSTEM_UID, true);
assertEquals(NotificationChannel.USER_LOCKED_LIGHTS
| NotificationChannel.USER_LOCKED_IMPORTANCE,
mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update2.getId(), false)
@@ -2000,21 +2067,22 @@ public class PreferencesHelperTest extends UiServiceTestCase {
@Test
public void testLockFields_visibilityAndDndAndBadge() {
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false,
+ UID_N_MR1, false);
assertEquals(0,
mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel().getId(), false)
.getUserLockedFields());
final NotificationChannel update1 = getChannel();
update1.setBypassDnd(true);
- mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update1, true);
+ mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update1, true, SYSTEM_UID, true);
assertEquals(NotificationChannel.USER_LOCKED_PRIORITY,
mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update1.getId(), false)
.getUserLockedFields());
final NotificationChannel update2 = getChannel();
update2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
- mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update2, true);
+ mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update2, true, SYSTEM_UID, true);
assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
| NotificationChannel.USER_LOCKED_VISIBILITY,
mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update2.getId(), false)
@@ -2022,7 +2090,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
final NotificationChannel update3 = getChannel();
update3.setShowBadge(false);
- mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update3, true);
+ mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update3, true, SYSTEM_UID, true);
assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
| NotificationChannel.USER_LOCKED_VISIBILITY
| NotificationChannel.USER_LOCKED_SHOW_BADGE,
@@ -2032,14 +2100,16 @@ public class PreferencesHelperTest extends UiServiceTestCase {
@Test
public void testLockFields_allowBubble() {
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false,
+ UID_N_MR1, false);
assertEquals(0,
mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel().getId(), false)
.getUserLockedFields());
final NotificationChannel update = getChannel();
update.setAllowBubbles(true);
- mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update, true);
+ mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update, true,
+ SYSTEM_UID, true);
assertEquals(NotificationChannel.USER_LOCKED_ALLOW_BUBBLE,
mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update.getId(), false)
.getUserLockedFields());
@@ -2047,15 +2117,19 @@ public class PreferencesHelperTest extends UiServiceTestCase {
@Test
public void testDeleteNonExistentChannel() throws Exception {
- mHelper.deleteNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, "does not exist");
+ mHelper.deleteNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, "does not exist",
+ UID_N_MR1, false);
}
@Test
public void testDoubleDeleteChannel() throws Exception {
NotificationChannel channel = getChannel();
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
- mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
- mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false,
+ UID_N_MR1, false);
+ mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(),
+ UID_N_MR1, false);
+ mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(),
+ UID_N_MR1, false);
assertEquals(2, mLogger.getCalls().size());
assertEquals(
NotificationChannelLogger.NotificationChannelEvent.NOTIFICATION_CHANNEL_CREATED,
@@ -2076,8 +2150,10 @@ public class PreferencesHelperTest extends UiServiceTestCase {
channel.enableVibration(true);
channel.setVibrationPattern(new long[]{100, 67, 145, 156});
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
- mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false,
+ UID_N_MR1, false);
+ mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(),
+ UID_N_MR1, false);
// Does not return deleted channel
NotificationChannel response =
@@ -2105,10 +2181,13 @@ public class PreferencesHelperTest extends UiServiceTestCase {
NotificationChannel channel2 =
new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_HIGH);
channelMap.put(channel2.getId(), channel2);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false,
+ UID_N_MR1, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, false,
+ UID_N_MR1, false);
- mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
+ mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(),
+ UID_N_MR1, false);
// Returns only non-deleted channels
List<NotificationChannel> channels =
@@ -2138,12 +2217,17 @@ public class PreferencesHelperTest extends UiServiceTestCase {
new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_HIGH);
NotificationChannel channel3 =
new NotificationChannel("id5", "a", NotificationManager.IMPORTANCE_HIGH);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, false);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, true, false);
-
- mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
- mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3.getId());
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false,
+ UID_N_MR1, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, false,
+ UID_N_MR1, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, true, false,
+ UID_N_MR1, false);
+
+ mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(),
+ UID_N_MR1, false);
+ mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3.getId(),
+ UID_N_MR1, false);
assertEquals(2, mHelper.getDeletedChannelCount(PKG_N_MR1, UID_N_MR1));
assertEquals(0, mHelper.getDeletedChannelCount("pkg2", UID_O));
@@ -2157,11 +2241,15 @@ public class PreferencesHelperTest extends UiServiceTestCase {
new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_NONE);
NotificationChannel channel3 =
new NotificationChannel("id5", "a", NotificationManager.IMPORTANCE_NONE);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, false);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, true, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false,
+ UID_N_MR1, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, false,
+ UID_N_MR1, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, true, false,
+ UID_N_MR1, false);
- mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3.getId());
+ mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3.getId(),
+ UID_N_MR1, false);
assertEquals(1, mHelper.getBlockedChannelCount(PKG_N_MR1, UID_N_MR1));
assertEquals(0, mHelper.getBlockedChannelCount("pkg2", UID_O));
@@ -2180,7 +2268,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
NotificationChannel channel = new NotificationChannel("id", "name",
NotificationManager.IMPORTANCE_MAX);
channel.setBypassDnd(true);
- mHelper.createNotificationChannel(PKG_N_MR1, 111, channel, true, true);
+ mHelper.createNotificationChannel(PKG_N_MR1, 111, channel, true, true,
+ 111, false);
assertEquals(0, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
uid).getList().size());
@@ -2194,15 +2283,18 @@ public class PreferencesHelperTest extends UiServiceTestCase {
NotificationManager.IMPORTANCE_MAX);
channel1.setBypassDnd(true);
channel1.setGroup(ncg.getId());
- mHelper.createNotificationChannelGroup(PKG_N_MR1, uid, ncg, /* fromTargetApp */ true);
- mHelper.createNotificationChannel(PKG_N_MR1, uid, channel1, true, /*has DND access*/ true);
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, uid, ncg, /* fromTargetApp */ true,
+ uid, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, uid, channel1, true, /*has DND access*/ true,
+ uid, false);
assertEquals(1, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
uid).getList().size());
// disable group
ncg.setBlocked(true);
- mHelper.createNotificationChannelGroup(PKG_N_MR1, uid, ncg, /* fromTargetApp */ false);
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, uid, ncg, /* fromTargetApp */ false,
+ SYSTEM_UID, true);
assertEquals(0, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
uid).getList().size());
}
@@ -2220,9 +2312,12 @@ public class PreferencesHelperTest extends UiServiceTestCase {
channel2.setBypassDnd(true);
channel3.setBypassDnd(true);
// has DND access, so can set bypassDnd attribute
- mHelper.createNotificationChannel(PKG_N_MR1, uid, channel1, true, /*has DND access*/ true);
- mHelper.createNotificationChannel(PKG_N_MR1, uid, channel2, true, true);
- mHelper.createNotificationChannel(PKG_N_MR1, uid, channel3, true, true);
+ mHelper.createNotificationChannel(PKG_N_MR1, uid, channel1, true, /*has DND access*/ true,
+ uid, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, uid, channel2, true, true,
+ uid, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, uid, channel3, true, true,
+ uid, false);
assertEquals(3, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
uid).getList().size());
@@ -2247,29 +2342,31 @@ public class PreferencesHelperTest extends UiServiceTestCase {
// expected result: areChannelsBypassingDnd = false
// setNotificationPolicy isn't called since areChannelsBypassingDnd was already false
NotificationChannel channel = new NotificationChannel("id1", "name1", IMPORTANCE_LOW);
- mHelper.createNotificationChannel(PKG_N_MR1, uid, channel, true, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, uid, channel, true, false,
+ uid, false);
assertFalse(mHelper.areChannelsBypassingDnd());
- verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
+ verify(mMockZenModeHelper, never()).setNotificationPolicy(any(), anyInt(), anyBoolean());
resetZenModeHelper();
// create notification channel that can bypass dnd
// expected result: areChannelsBypassingDnd = true
NotificationChannel channel2 = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
channel2.setBypassDnd(true);
- mHelper.createNotificationChannel(PKG_N_MR1, uid, channel2, true, true);
+ mHelper.createNotificationChannel(PKG_N_MR1, uid, channel2, true, true,
+ uid, false);
assertTrue(mHelper.areChannelsBypassingDnd());
- verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
+ verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(), anyInt(), anyBoolean());
resetZenModeHelper();
// delete channels
- mHelper.deleteNotificationChannel(PKG_N_MR1, uid, channel.getId());
+ mHelper.deleteNotificationChannel(PKG_N_MR1, uid, channel.getId(), uid, false);
assertTrue(mHelper.areChannelsBypassingDnd()); // channel2 can still bypass DND
- verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
+ verify(mMockZenModeHelper, never()).setNotificationPolicy(any(), anyInt(), anyBoolean());
resetZenModeHelper();
- mHelper.deleteNotificationChannel(PKG_N_MR1, uid, channel2.getId());
+ mHelper.deleteNotificationChannel(PKG_N_MR1, uid, channel2.getId(), uid, false);
assertFalse(mHelper.areChannelsBypassingDnd());
- verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
+ verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(), anyInt(), anyBoolean());
resetZenModeHelper();
}
@@ -2282,18 +2379,20 @@ public class PreferencesHelperTest extends UiServiceTestCase {
// expected result: areChannelsBypassingDnd = false
// setNotificationPolicy isn't called since areChannelsBypassingDnd was already false
NotificationChannel channel = new NotificationChannel("id1", "name1", IMPORTANCE_LOW);
- mHelper.createNotificationChannel(PKG_N_MR1, uid, channel, true, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, uid, channel, true, false,
+ uid, false);
assertFalse(mHelper.areChannelsBypassingDnd());
- verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
+ verify(mMockZenModeHelper, never()).setNotificationPolicy(any(), anyInt(), anyBoolean());
resetZenModeHelper();
// Recreate a channel & now the app has dnd access granted and can set the bypass dnd field
NotificationChannel update = new NotificationChannel("id1", "name1", IMPORTANCE_LOW);
update.setBypassDnd(true);
- mHelper.createNotificationChannel(PKG_N_MR1, uid, update, true, true);
+ mHelper.createNotificationChannel(PKG_N_MR1, uid, update, true, true,
+ uid, false);
assertTrue(mHelper.areChannelsBypassingDnd());
- verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
+ verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(), anyInt(), anyBoolean());
resetZenModeHelper();
}
@@ -2306,29 +2405,31 @@ public class PreferencesHelperTest extends UiServiceTestCase {
// expected result: areChannelsBypassingDnd = false
// setNotificationPolicy isn't called since areChannelsBypassingDnd was already false
NotificationChannel channel = new NotificationChannel("id1", "name1", IMPORTANCE_LOW);
- mHelper.createNotificationChannel(PKG_N_MR1, uid, channel, true, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, uid, channel, true, false,
+ uid, false);
assertFalse(mHelper.areChannelsBypassingDnd());
- verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
+ verify(mMockZenModeHelper, never()).setNotificationPolicy(any(), anyInt(), anyBoolean());
resetZenModeHelper();
// create notification channel that can bypass dnd, using local app level settings
// expected result: areChannelsBypassingDnd = true
NotificationChannel channel2 = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
channel2.setBypassDnd(true);
- mHelper.createNotificationChannel(PKG_N_MR1, uid, channel2, true, true);
+ mHelper.createNotificationChannel(PKG_N_MR1, uid, channel2, true, true,
+ uid, false);
assertTrue(mHelper.areChannelsBypassingDnd());
- verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
+ verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(), anyInt(), anyBoolean());
resetZenModeHelper();
// delete channels
- mHelper.deleteNotificationChannel(PKG_N_MR1, uid, channel.getId());
+ mHelper.deleteNotificationChannel(PKG_N_MR1, uid, channel.getId(), uid, false);
assertTrue(mHelper.areChannelsBypassingDnd()); // channel2 can still bypass DND
- verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
+ verify(mMockZenModeHelper, never()).setNotificationPolicy(any(), anyInt(), anyBoolean());
resetZenModeHelper();
- mHelper.deleteNotificationChannel(PKG_N_MR1, uid, channel2.getId());
+ mHelper.deleteNotificationChannel(PKG_N_MR1, uid, channel2.getId(), uid, false);
assertFalse(mHelper.areChannelsBypassingDnd());
- verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
+ verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(), anyInt(), anyBoolean());
resetZenModeHelper();
}
@@ -2350,13 +2451,16 @@ public class PreferencesHelperTest extends UiServiceTestCase {
// expected result: areChannelsBypassingDnd = false
NotificationChannelGroup group = new NotificationChannelGroup("group", "group");
group.setBlocked(true);
- mHelper.createNotificationChannelGroup(PKG_N_MR1, uid, group, false);
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, uid, group, false,
+ SYSTEM_UID, true);
NotificationChannel channel2 = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
channel2.setGroup("group");
channel2.setBypassDnd(true);
- mHelper.createNotificationChannel(PKG_N_MR1, uid, channel2, true, true);
+ mHelper.createNotificationChannel(PKG_N_MR1, uid, channel2, true, true,
+ uid, false);
assertFalse(mHelper.areChannelsBypassingDnd());
- verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
+ verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(),
+ anyInt(), anyBoolean());
resetZenModeHelper();
}
@@ -2377,9 +2481,10 @@ public class PreferencesHelperTest extends UiServiceTestCase {
// expected result: areChannelsBypassingDnd = false
NotificationChannel channel2 = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
channel2.setBypassDnd(true);
- mHelper.createNotificationChannel(PKG_N_MR1, uid, channel2, true, true);
+ mHelper.createNotificationChannel(PKG_N_MR1, uid, channel2, true, true,
+ uid, false);
assertFalse(mHelper.areChannelsBypassingDnd());
- verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
+ verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(), anyInt(), anyBoolean());
resetZenModeHelper();
}
@@ -2400,9 +2505,10 @@ public class PreferencesHelperTest extends UiServiceTestCase {
// expected result: areChannelsBypassingDnd = false
NotificationChannel channel2 = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
channel2.setBypassDnd(true);
- mHelper.createNotificationChannel(PKG_N_MR1, uid, channel2, true, true);
+ mHelper.createNotificationChannel(PKG_N_MR1, uid, channel2, true, true,
+ uid, false);
assertFalse(mHelper.areChannelsBypassingDnd());
- verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
+ verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(), anyInt(), anyBoolean());
resetZenModeHelper();
}
@@ -2415,25 +2521,26 @@ public class PreferencesHelperTest extends UiServiceTestCase {
// expected result: areChannelsBypassingDnd = false
// setNotificationPolicy isn't called since areChannelsBypassingDnd was already false
NotificationChannel channel = new NotificationChannel("id1", "name1", IMPORTANCE_LOW);
- mHelper.createNotificationChannel(PKG_N_MR1, uid, channel, true, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, uid, channel, true, false,
+ uid, false);
assertFalse(mHelper.areChannelsBypassingDnd());
- verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
+ verify(mMockZenModeHelper, never()).setNotificationPolicy(any(), anyInt(), anyBoolean());
resetZenModeHelper();
// update channel so it CAN bypass dnd:
// expected result: areChannelsBypassingDnd = true
channel.setBypassDnd(true);
- mHelper.updateNotificationChannel(PKG_N_MR1, uid, channel, true);
+ mHelper.updateNotificationChannel(PKG_N_MR1, uid, channel, true, SYSTEM_UID, true);
assertTrue(mHelper.areChannelsBypassingDnd());
- verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
+ verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(), anyInt(), anyBoolean());
resetZenModeHelper();
// update channel so it can't bypass dnd:
// expected result: areChannelsBypassingDnd = false
channel.setBypassDnd(false);
- mHelper.updateNotificationChannel(PKG_N_MR1, uid, channel, true);
+ mHelper.updateNotificationChannel(PKG_N_MR1, uid, channel, true, SYSTEM_UID, true);
assertFalse(mHelper.areChannelsBypassingDnd());
- verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
+ verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(), anyInt(), anyBoolean());
resetZenModeHelper();
}
@@ -2448,7 +2555,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
mPermissionHelper, mLogger,
mAppOpsManager, mStatsEventBuilderFactory, false);
assertFalse(mHelper.areChannelsBypassingDnd());
- verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
+ verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(), anyInt(), anyBoolean());
resetZenModeHelper();
}
@@ -2461,7 +2568,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
mPermissionHelper, mLogger,
mAppOpsManager, mStatsEventBuilderFactory, false);
assertFalse(mHelper.areChannelsBypassingDnd());
- verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
+ verify(mMockZenModeHelper, never()).setNotificationPolicy(any(), anyInt(), anyBoolean());
resetZenModeHelper();
}
@@ -2472,14 +2579,17 @@ public class PreferencesHelperTest extends UiServiceTestCase {
new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
channel.setVibrationPattern(vibration);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
- mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false,
+ UID_N_MR1, false);
+ mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(),
+ UID_N_MR1, false);
NotificationChannel newChannel = new NotificationChannel(
channel.getId(), channel.getName(), NotificationManager.IMPORTANCE_HIGH);
newChannel.setVibrationPattern(new long[]{100});
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, newChannel, true, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, newChannel, true, false,
+ UID_N_MR1, false);
// No long deleted, using old settings
compareChannels(channel,
@@ -2491,7 +2601,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
assertTrue(mHelper.onlyHasDefaultChannel(PKG_N_MR1, UID_N_MR1));
assertFalse(mHelper.onlyHasDefaultChannel(PKG_O, UID_O));
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false,
+ UID_N_MR1, false);
assertFalse(mHelper.onlyHasDefaultChannel(PKG_N_MR1, UID_N_MR1));
}
@@ -2499,7 +2610,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
public void testCreateChannel_defaultChannelId() throws Exception {
try {
mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, new NotificationChannel(
- NotificationChannel.DEFAULT_CHANNEL_ID, "ha", IMPORTANCE_HIGH), true, false);
+ NotificationChannel.DEFAULT_CHANNEL_ID, "ha", IMPORTANCE_HIGH), true, false,
+ UID_N_MR1, false);
fail("Allowed to create default channel");
} catch (IllegalArgumentException e) {
// pass
@@ -2513,7 +2625,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
channel.setVibrationPattern(vibration);
- assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false));
+ assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false,
+ UID_N_MR1, false));
NotificationChannel newChannel = new NotificationChannel(
channel.getId(), channel.getName(), NotificationManager.IMPORTANCE_HIGH);
@@ -2524,7 +2637,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
newChannel.setShowBadge(!channel.canShowBadge());
assertFalse(mHelper.createNotificationChannel(
- PKG_N_MR1, UID_N_MR1, newChannel, true, false));
+ PKG_N_MR1, UID_N_MR1, newChannel, true, false,
+ UID_N_MR1, false));
// Old settings not overridden
compareChannels(channel,
@@ -2542,7 +2656,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
final NotificationChannel channel = new NotificationChannel("id2", "name2",
NotificationManager.IMPORTANCE_DEFAULT);
channel.setSound(sound, mAudioAttributes);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false,
+ UID_N_MR1, false);
assertEquals(sound, mHelper.getNotificationChannel(
PKG_N_MR1, UID_N_MR1, channel.getId(), false).getSound());
}
@@ -2554,8 +2669,10 @@ public class PreferencesHelperTest extends UiServiceTestCase {
NotificationChannel channel2 =
new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false,
+ UID_N_MR1, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false,
+ UID_N_MR1, false);
mHelper.permanentlyDeleteNotificationChannels(PKG_N_MR1, UID_N_MR1);
@@ -2576,14 +2693,20 @@ public class PreferencesHelperTest extends UiServiceTestCase {
new NotificationChannel("deleted", "belongs to deleted", IMPORTANCE_DEFAULT);
groupedAndDeleted.setGroup("totally");
- mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, notDeleted, true);
- mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, deleted, true);
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, notDeleted, true,
+ UID_N_MR1, false);
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, deleted, true,
+ UID_N_MR1, false);
mHelper.createNotificationChannel(
- PKG_N_MR1, UID_N_MR1, nonGroupedNonDeletedChannel, true, false);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, groupedAndDeleted, true, false);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, groupedButNotDeleted, true, false);
+ PKG_N_MR1, UID_N_MR1, nonGroupedNonDeletedChannel, true, false,
+ UID_N_MR1, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, groupedAndDeleted, true, false,
+ UID_N_MR1, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, groupedButNotDeleted, true, false,
+ UID_N_MR1, false);
- mHelper.deleteNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, deleted.getId());
+ mHelper.deleteNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, deleted.getId(),
+ UID_N_MR1, false);
assertNull(mHelper.getNotificationChannelGroup(deleted.getId(), PKG_N_MR1, UID_N_MR1));
assertNotNull(
@@ -2626,10 +2749,14 @@ public class PreferencesHelperTest extends UiServiceTestCase {
convo.setGroup("not");
convo.setConversationId("not deleted", "banana");
- mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, notDeleted, true);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, base, true, false);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, convo, true, false);
- mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, notDeleted, true);
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, notDeleted, true,
+ UID_N_MR1, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, base, true, false,
+ UID_N_MR1, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, convo, true, false,
+ UID_N_MR1, false);
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, notDeleted, true,
+ UID_N_MR1, false);
NotificationChannelGroup g
= mHelper.getNotificationChannelGroup(notDeleted.getId(), PKG_N_MR1, UID_N_MR1);
@@ -2679,7 +2806,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
// Deleted
NotificationChannel channel1 =
new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false,
+ UID_N_MR1, false);
assertTrue(mHelper.onPackagesChanged(true, USER_SYSTEM, new String[]{PKG_N_MR1},
new int[]{UID_N_MR1}));
@@ -2688,7 +2816,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
PKG_N_MR1, UID_N_MR1, true).getList().size());
// Not deleted
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false,
+ UID_N_MR1, false);
assertFalse(mHelper.onPackagesChanged(false, USER_SYSTEM,
new String[]{PKG_N_MR1}, new int[]{UID_N_MR1}));
@@ -2698,9 +2827,11 @@ public class PreferencesHelperTest extends UiServiceTestCase {
@Test
public void testOnPackageChanged_packageRemoval_groups() throws Exception {
NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
- mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true,
+ UID_N_MR1, false);
NotificationChannelGroup ncg2 = new NotificationChannelGroup("group2", "name2");
- mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true,
+ UID_N_MR1, false);
mHelper.onPackagesChanged(true, USER_SYSTEM, new String[]{PKG_N_MR1}, new int[]{
UID_N_MR1});
@@ -2712,7 +2843,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
@Test
public void testOnPackageChange_downgradeTargetSdk() throws Exception {
// create channel as api 26
- mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false,
+ UID_N_MR1, false);
// install new app version targeting 25
final ApplicationInfo legacy = new ApplicationInfo();
@@ -2731,9 +2863,11 @@ public class PreferencesHelperTest extends UiServiceTestCase {
public void testClearData() {
ArraySet<Pair<String, Integer>> pkgPair = new ArraySet<>();
pkgPair.add(new Pair<>(PKG_O, UID_O));
- mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false,
+ UID_O, false);
mHelper.createNotificationChannelGroup(
- PKG_O, UID_O, new NotificationChannelGroup("1", "bye"), true);
+ PKG_O, UID_O, new NotificationChannelGroup("1", "bye"), true,
+ UID_O, false);
mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, pkgPair);
mHelper.setNotificationDelegate(PKG_O, UID_O, "", 1);
mHelper.setBubblesAllowed(PKG_O, UID_O, DEFAULT_BUBBLE_PREFERENCE);
@@ -2750,7 +2884,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
assertEquals(0, mHelper.getNotificationChannelGroups(PKG_O, UID_O).size());
NotificationChannel channel = getChannel();
- mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false,
+ UID_O, false);
assertTrue(channel.isImportanceLockedByCriticalDeviceFunction());
}
@@ -2764,7 +2899,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
@Test
public void testCreateGroup() {
NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
- mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true,
+ UID_N_MR1, false);
assertEquals(ncg,
mHelper.getNotificationChannelGroups(PKG_N_MR1, UID_N_MR1).iterator().next());
verify(mHandler, never()).requestSort();
@@ -2781,7 +2917,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
channel1.setGroup("garbage");
try {
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false,
+ UID_N_MR1, false);
fail("Created a channel with a bad group");
} catch (IllegalArgumentException e) {
}
@@ -2791,11 +2928,13 @@ public class PreferencesHelperTest extends UiServiceTestCase {
@Test
public void testCannotCreateChannel_goodGroup() {
NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
- mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true,
+ UID_N_MR1, false);
NotificationChannel channel1 =
new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
channel1.setGroup(ncg.getId());
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false,
+ UID_N_MR1, false);
assertEquals(ncg.getId(), mHelper.getNotificationChannel(
PKG_N_MR1, UID_N_MR1, channel1.getId(), false).getGroup());
@@ -2804,29 +2943,36 @@ public class PreferencesHelperTest extends UiServiceTestCase {
@Test
public void testGetChannelGroups() {
NotificationChannelGroup unused = new NotificationChannelGroup("unused", "s");
- mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, unused, true);
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, unused, true,
+ UID_N_MR1, false);
NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
- mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true,
+ UID_N_MR1, false);
NotificationChannelGroup ncg2 = new NotificationChannelGroup("group2", "name2");
- mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true,
+ UID_N_MR1, false);
NotificationChannel channel1 =
new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
channel1.setGroup(ncg.getId());
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false,
+ UID_N_MR1, false);
NotificationChannel channel1a =
new NotificationChannel("id1a", "name1", NotificationManager.IMPORTANCE_HIGH);
channel1a.setGroup(ncg.getId());
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1a, true, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1a, true, false,
+ UID_N_MR1, false);
NotificationChannel channel2 =
new NotificationChannel("id2", "name1", NotificationManager.IMPORTANCE_HIGH);
channel2.setGroup(ncg2.getId());
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, false,
+ UID_N_MR1, false);
NotificationChannel channel3 =
new NotificationChannel("id3", "name1", NotificationManager.IMPORTANCE_HIGH);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, true, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, true, false,
+ UID_N_MR1, false);
List<NotificationChannelGroup> actual = mHelper.getNotificationChannelGroups(
PKG_N_MR1, UID_N_MR1, true, true, false).getList();
@@ -2855,16 +3001,19 @@ public class PreferencesHelperTest extends UiServiceTestCase {
@Test
public void testGetChannelGroups_noSideEffects() {
NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
- mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true,
+ UID_N_MR1, false);
NotificationChannel channel1 =
new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
channel1.setGroup(ncg.getId());
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false,
+ UID_N_MR1, false);
mHelper.getNotificationChannelGroups(PKG_N_MR1, UID_N_MR1, true, true, false).getList();
channel1.setImportance(IMPORTANCE_LOW);
- mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true);
+ mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true,
+ UID_N_MR1, false);
List<NotificationChannelGroup> actual = mHelper.getNotificationChannelGroups(
PKG_N_MR1, UID_N_MR1, true, true, false).getList();
@@ -2880,14 +3029,17 @@ public class PreferencesHelperTest extends UiServiceTestCase {
@Test
public void testGetChannelGroups_includeEmptyGroups() {
NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
- mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true,
+ UID_N_MR1, false);
NotificationChannelGroup ncgEmpty = new NotificationChannelGroup("group2", "name2");
- mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncgEmpty, true);
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncgEmpty, true,
+ UID_N_MR1, false);
NotificationChannel channel1 =
new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
channel1.setGroup(ncg.getId());
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false,
+ UID_N_MR1, false);
List<NotificationChannelGroup> actual = mHelper.getNotificationChannelGroups(
PKG_N_MR1, UID_N_MR1, false, false, true).getList();
@@ -2906,13 +3058,15 @@ public class PreferencesHelperTest extends UiServiceTestCase {
@Test
public void testCreateChannel_updateName() {
NotificationChannel nc = new NotificationChannel("id", "hello", IMPORTANCE_DEFAULT);
- assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false));
+ assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false,
+ UID_N_MR1, false));
NotificationChannel actual =
mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "id", false);
assertEquals("hello", actual.getName());
nc = new NotificationChannel("id", "goodbye", IMPORTANCE_HIGH);
- assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false));
+ assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false,
+ UID_N_MR1, false));
actual = mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "id", false);
assertEquals("goodbye", actual.getName());
@@ -2924,16 +3078,19 @@ public class PreferencesHelperTest extends UiServiceTestCase {
@Test
public void testCreateChannel_addToGroup() {
NotificationChannelGroup group = new NotificationChannelGroup("group", "group");
- mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true);
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true,
+ UID_N_MR1, false);
NotificationChannel nc = new NotificationChannel("id", "hello", IMPORTANCE_DEFAULT);
- assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false));
+ assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false,
+ UID_N_MR1, false));
NotificationChannel actual =
mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "id", false);
assertNull(actual.getGroup());
nc = new NotificationChannel("id", "hello", IMPORTANCE_HIGH);
nc.setGroup(group.getId());
- assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false));
+ assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false,
+ UID_N_MR1, false));
actual = mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "id", false);
assertNotNull(actual.getGroup());
@@ -2969,14 +3126,16 @@ public class PreferencesHelperTest extends UiServiceTestCase {
int numChannels = ThreadLocalRandom.current().nextInt(1, 10);
for (int j = 0; j < numChannels; j++) {
mHelper.createNotificationChannel(pkgName, UID_N_MR1,
- new NotificationChannel("" + j, "a", IMPORTANCE_HIGH), true, false);
+ new NotificationChannel("" + j, "a", IMPORTANCE_HIGH), true, false,
+ UID_N_MR1, false);
}
expectedChannels.put(pkgName, numChannels);
}
// delete the first channel of the first package
String pkg = expectedChannels.keyAt(0);
- mHelper.deleteNotificationChannel("pkg" + 0, UID_N_MR1, "0");
+ mHelper.deleteNotificationChannel("pkg" + 0, UID_N_MR1, "0",
+ UID_N_MR1, false);
// dump should not include deleted channels
int count = expectedChannels.get(pkg);
expectedChannels.put(pkg, count - 1);
@@ -3012,10 +3171,14 @@ public class PreferencesHelperTest extends UiServiceTestCase {
new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
NotificationChannel channel3 = new NotificationChannel("id3", "name3", IMPORTANCE_HIGH);
- mHelper.createNotificationChannel(PKG_P, UID_P, channel1, true, false);
- mHelper.createNotificationChannel(PKG_P, UID_P, channel2, false, false);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, false, false);
- mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false);
+ mHelper.createNotificationChannel(PKG_P, UID_P, channel1, true, false,
+ UID_P, false);
+ mHelper.createNotificationChannel(PKG_P, UID_P, channel2, false, false,
+ UID_P, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, false, false,
+ UID_N_MR1, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false,
+ UID_N_MR1, false);
// in the json array, all of the individual package preferences are simply elements in the
// values array. this set is to collect expected outputs for each of our packages.
@@ -3328,7 +3491,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
@Test
public void testIsGroupBlocked_notBlocked() throws Exception {
NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
- mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true);
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true,
+ UID_N_MR1, false);
assertFalse(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, group.getId()));
}
@@ -3336,9 +3500,11 @@ public class PreferencesHelperTest extends UiServiceTestCase {
@Test
public void testIsGroupBlocked_blocked() throws Exception {
NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
- mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true);
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true,
+ UID_N_MR1, false);
group.setBlocked(true);
- mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, false);
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, false,
+ UID_N_MR1, false);
assertTrue(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, group.getId()));
}
@@ -3347,27 +3513,32 @@ public class PreferencesHelperTest extends UiServiceTestCase {
public void testIsGroupBlocked_appCannotCreateAsBlocked() throws Exception {
NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
group.setBlocked(true);
- mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true);
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true,
+ UID_N_MR1, false);
assertFalse(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, group.getId()));
NotificationChannelGroup group3 = group.clone();
group3.setBlocked(false);
- mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group3, true);
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group3, true,
+ UID_N_MR1, false);
assertFalse(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, group.getId()));
}
@Test
public void testIsGroup_appCannotResetBlock() throws Exception {
NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
- mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true);
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true,
+ UID_N_MR1, false);
NotificationChannelGroup group2 = group.clone();
group2.setBlocked(true);
- mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group2, false);
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group2, false,
+ UID_N_MR1, false);
assertTrue(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, group.getId()));
NotificationChannelGroup group3 = group.clone();
group3.setBlocked(false);
- mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group3, true);
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group3, true,
+ UID_N_MR1, false);
assertTrue(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, group.getId()));
}
@@ -3375,8 +3546,10 @@ public class PreferencesHelperTest extends UiServiceTestCase {
public void testGetNotificationChannelGroupWithChannels() throws Exception {
NotificationChannelGroup group = new NotificationChannelGroup("group", "group");
NotificationChannelGroup other = new NotificationChannelGroup("something else", "name");
- mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true);
- mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, other, true);
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true,
+ UID_N_MR1, false);
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, other, true,
+ UID_N_MR1, false);
NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_DEFAULT);
a.setGroup(group.getId());
@@ -3386,11 +3559,16 @@ public class PreferencesHelperTest extends UiServiceTestCase {
c.setGroup(group.getId());
NotificationChannel d = new NotificationChannel("d", "d", IMPORTANCE_DEFAULT);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, a, true, false);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, b, true, false);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, c, true, false);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, d, true, false);
- mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, c.getId());
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, a, true, false,
+ UID_N_MR1, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, b, true, false,
+ UID_N_MR1, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, c, true, false,
+ UID_N_MR1, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, d, true, false,
+ UID_N_MR1, false);
+ mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, c.getId(),
+ UID_N_MR1, false);
NotificationChannelGroup retrieved = mHelper.getNotificationChannelGroupWithChannels(
PKG_N_MR1, UID_N_MR1, group.getId(), true);
@@ -3409,7 +3587,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
test.setBypassDnd(true);
- mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, test, true, false);
+ mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, test, true, false,
+ SYSTEM_UID, true);
assertFalse(mHelper.getNotificationChannel(SYSTEM_PKG, SYSTEM_UID, "A", false)
.canBypassDnd());
@@ -3420,7 +3599,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
test.setBypassDnd(true);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, test, true, true);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, test, true, true,
+ UID_N_MR1, false);
assertTrue(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "A", false).canBypassDnd());
}
@@ -3430,7 +3610,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
test.setBypassDnd(true);
- mHelper.createNotificationChannel(PKG_N_MR1, 1000, test, true, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, 1000, test, true, false,
+ UID_N_MR1, false);
assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, 1000, "A", false).canBypassDnd());
}
@@ -3438,11 +3619,13 @@ public class PreferencesHelperTest extends UiServiceTestCase {
@Test
public void testAndroidPkgCannotBypassDnd_update() throws Exception {
NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
- mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, test, true, false);
+ mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, test, true, false,
+ SYSTEM_UID, true);
NotificationChannel update = new NotificationChannel("A", "a", IMPORTANCE_LOW);
update.setBypassDnd(true);
- assertFalse(mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, update, true, false));
+ assertFalse(mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, update, true, false,
+ SYSTEM_UID, true));
assertFalse(mHelper.getNotificationChannel(SYSTEM_PKG, SYSTEM_UID, "A", false)
.canBypassDnd());
@@ -3451,11 +3634,13 @@ public class PreferencesHelperTest extends UiServiceTestCase {
@Test
public void testDndPkgCanBypassDnd_update() throws Exception {
NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, test, true, true);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, test, true, true,
+ UID_N_MR1, false);
NotificationChannel update = new NotificationChannel("A", "a", IMPORTANCE_LOW);
update.setBypassDnd(true);
- assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, update, true, true));
+ assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, update, true, true,
+ UID_N_MR1, false));
assertTrue(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "A", false).canBypassDnd());
}
@@ -3463,10 +3648,12 @@ public class PreferencesHelperTest extends UiServiceTestCase {
@Test
public void testNormalPkgCannotBypassDnd_update() {
NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
- mHelper.createNotificationChannel(PKG_N_MR1, 1000, test, true, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, 1000, test, true, false,
+ UID_N_MR1, false);
NotificationChannel update = new NotificationChannel("A", "a", IMPORTANCE_LOW);
update.setBypassDnd(true);
- mHelper.createNotificationChannel(PKG_N_MR1, 1000, update, true, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, 1000, update, true, false,
+ UID_N_MR1, false);
assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, 1000, "A", false).canBypassDnd());
}
@@ -3726,12 +3913,14 @@ public class PreferencesHelperTest extends UiServiceTestCase {
assertTrue(mHelper.isImportanceLocked(PKG_O, UID_O));
NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
- mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false,
+ UID_O, false);
NotificationChannel update = new NotificationChannel("a", "a", IMPORTANCE_NONE);
update.setAllowBubbles(false);
- mHelper.updateNotificationChannel(PKG_O, UID_O, update, true);
+ mHelper.updateNotificationChannel(PKG_O, UID_O, update, true,
+ UID_O, false);
assertEquals(IMPORTANCE_HIGH,
mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
@@ -3745,12 +3934,12 @@ public class PreferencesHelperTest extends UiServiceTestCase {
toAdd.add(new Pair<>(PKG_O, UID_O));
mHelper.updateDefaultApps(0, null, toAdd);
NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
- mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false, UID_O, false);
NotificationChannel update = new NotificationChannel("a", "a", IMPORTANCE_NONE);
update.setAllowBubbles(false);
- mHelper.updateNotificationChannel(PKG_O, UID_O, update, true);
+ mHelper.updateNotificationChannel(PKG_O, UID_O, update, true, UID_O, false);
assertEquals(IMPORTANCE_HIGH,
mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
@@ -3763,12 +3952,12 @@ public class PreferencesHelperTest extends UiServiceTestCase {
when(mPermissionHelper.isPermissionFixed(PKG_O, 0)).thenReturn(true);
NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_NONE);
- mHelper.createNotificationChannel(PKG_O, UID_O, a, false, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, a, false, false, UID_O, false);
NotificationChannel update = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
update.setAllowBubbles(false);
- mHelper.updateNotificationChannel(PKG_O, UID_O, update, true);
+ mHelper.updateNotificationChannel(PKG_O, UID_O, update, true, UID_O, false);
assertEquals(IMPORTANCE_HIGH,
mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
@@ -3782,12 +3971,12 @@ public class PreferencesHelperTest extends UiServiceTestCase {
NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
a.setBlockable(true);
- mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false, UID_O, false);
NotificationChannel update = new NotificationChannel("a", "a", IMPORTANCE_NONE);
update.setAllowBubbles(false);
- mHelper.updateNotificationChannel(PKG_O, UID_O, update, true);
+ mHelper.updateNotificationChannel(PKG_O, UID_O, update, true, UID_O, false);
assertEquals(IMPORTANCE_NONE,
mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
@@ -3800,12 +3989,12 @@ public class PreferencesHelperTest extends UiServiceTestCase {
when(mPermissionHelper.isPermissionFixed(PKG_O, 0)).thenReturn(false);
NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
- mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false, UID_O, false);
NotificationChannel update = new NotificationChannel("a", "a", IMPORTANCE_NONE);
update.setAllowBubbles(false);
- mHelper.updateNotificationChannel(PKG_O, UID_O, update, true);
+ mHelper.updateNotificationChannel(PKG_O, UID_O, update, true, UID_O, false);
assertEquals(IMPORTANCE_NONE,
mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
@@ -3819,9 +4008,11 @@ public class PreferencesHelperTest extends UiServiceTestCase {
NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT);
// different uids, same package
- mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
- mHelper.createNotificationChannel(PKG_O, UID_O, b, false, false);
- mHelper.createNotificationChannel(PKG_O, UserHandle.PER_USER_RANGE + 1, c, true, true);
+ mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false, UID_O, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, b, false, false,
+ SYSTEM_UID, true);
+ mHelper.createNotificationChannel(PKG_O, UserHandle.PER_USER_RANGE + 1, c, true, true,
+ UserHandle.PER_USER_RANGE + 1, false);
UserInfo user = new UserInfo();
user.id = 0;
@@ -3859,7 +4050,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
mHelper.updateFixedImportance(users);
NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
- mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false, UID_O, false);
assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
.isImportanceLockedByCriticalDeviceFunction());
@@ -3871,9 +4062,10 @@ public class PreferencesHelperTest extends UiServiceTestCase {
NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT);
// different uids, same package
- mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
- mHelper.createNotificationChannel(PKG_O, UID_O, b, false, false);
- mHelper.createNotificationChannel(PKG_O, UserHandle.PER_USER_RANGE + 1, c, true, true);
+ mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false, UID_O, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, b, false, false, UID_O, false);
+ mHelper.createNotificationChannel(PKG_O, UserHandle.PER_USER_RANGE + 1, c, true, true,
+ UID_O, false);
ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
toAdd.add(new Pair<>(PKG_O, UID_O));
@@ -3892,8 +4084,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
public void testUpdateDefaultApps_add_onlyGivenPkg() {
NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
- mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, b, false, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false, UID_O, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, b, false, false, UID_O, false);
ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
toAdd.add(new Pair<>(PKG_O, UID_O));
@@ -3910,8 +4102,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
// different uids, same package
- mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
- mHelper.createNotificationChannel(PKG_O, UID_O, b, false, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false, UID_O, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, b, false, false, SYSTEM_UID, true);
ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
toAdd.add(new Pair<>(PKG_O, UID_O));
@@ -3936,8 +4128,10 @@ public class PreferencesHelperTest extends UiServiceTestCase {
public void testUpdateDefaultApps_addAndRemove() {
NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
- mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, b, false, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false,
+ UID_O, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, b, false, false,
+ UID_N_MR1, false);
ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
toAdd.add(new Pair<>(PKG_O, UID_O));
@@ -3975,7 +4169,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
public void testUpdateDefaultApps_channelDoesNotExistYet() {
NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
- mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false, UID_O, false);
ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
toAdd.add(new Pair<>(PKG_O, UID_O));
@@ -3984,7 +4178,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
.isImportanceLockedByCriticalDeviceFunction());
- mHelper.createNotificationChannel(PKG_O, UID_O, b, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, b, true, false, UID_O, false);
assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false)
.isImportanceLockedByCriticalDeviceFunction());
}
@@ -3992,7 +4186,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
@Test
public void testUpdateNotificationChannel_defaultAppLockedImportance() {
NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
- mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false, UID_O, false);
ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
toAdd.add(new Pair<>(PKG_O, UID_O));
mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
@@ -4000,19 +4194,20 @@ public class PreferencesHelperTest extends UiServiceTestCase {
NotificationChannel update = new NotificationChannel("a", "a", IMPORTANCE_NONE);
update.setAllowBubbles(false);
- mHelper.updateNotificationChannel(PKG_O, UID_O, update, true);
+ mHelper.updateNotificationChannel(PKG_O, UID_O, update, true, SYSTEM_UID, true);
assertEquals(IMPORTANCE_HIGH,
mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
assertEquals(false,
mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).canBubble());
- mHelper.updateNotificationChannel(PKG_O, UID_O, update, false);
+ mHelper.updateNotificationChannel(PKG_O, UID_O, update, false, UID_O, false);
assertEquals(IMPORTANCE_HIGH,
mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
NotificationChannel updateImportanceLow = new NotificationChannel("a", "a",
IMPORTANCE_LOW);
- mHelper.updateNotificationChannel(PKG_O, UID_O, updateImportanceLow, true);
+ mHelper.updateNotificationChannel(PKG_O, UID_O, updateImportanceLow, true,
+ SYSTEM_UID, true);
assertEquals(IMPORTANCE_LOW,
mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
}
@@ -4024,7 +4219,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
- mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false, UID_O, false);
assertTrue(a.isImportanceLockedByCriticalDeviceFunction());
}
@@ -4050,7 +4245,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
assertTrue(mHelper.isImportanceLocked(PKG_O, UID_O));
NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
- mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false, UID_O, false);
// Still locked by permission if not role
assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
@@ -4078,7 +4273,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
assertTrue(mHelper.isImportanceLocked(PKG_O, UID_O));
NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
- mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false, UID_O, false);
// Still locked by role if not permission
assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
@@ -4090,7 +4285,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
NotificationChannel channel1 =
new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
- mHelper.createNotificationChannel(PKG_O, UID_O, channel1, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, channel1, true, false, UID_O, false);
// clear data
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, true,
@@ -4144,14 +4339,14 @@ public class PreferencesHelperTest extends UiServiceTestCase {
for (int i = 0; i < NOTIFICATION_CHANNEL_COUNT_LIMIT; i++) {
NotificationChannel channel = new NotificationChannel(String.valueOf(i),
String.valueOf(i), NotificationManager.IMPORTANCE_HIGH);
- mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, true);
+ mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, true, UID_O, false);
}
try {
NotificationChannel channel = new NotificationChannel(
String.valueOf(NOTIFICATION_CHANNEL_COUNT_LIMIT),
String.valueOf(NOTIFICATION_CHANNEL_COUNT_LIMIT),
NotificationManager.IMPORTANCE_HIGH);
- mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, true);
+ mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, true, UID_O, false);
fail("Allowed to create too many notification channels");
} catch (IllegalStateException e) {
// great
@@ -4167,7 +4362,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
for (int i = 0; i < NOTIFICATION_CHANNEL_COUNT_LIMIT; i++) {
NotificationChannel channel = new NotificationChannel(String.valueOf(i),
String.valueOf(i), NotificationManager.IMPORTANCE_HIGH);
- mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, true);
+ mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, true, UID_O, false);
}
final String xml = "<ranking version=\"1\">\n"
@@ -4200,13 +4395,15 @@ public class PreferencesHelperTest extends UiServiceTestCase {
for (int i = 0; i < NOTIFICATION_CHANNEL_GROUP_COUNT_LIMIT; i++) {
NotificationChannelGroup group = new NotificationChannelGroup(String.valueOf(i),
String.valueOf(i));
- mHelper.createNotificationChannelGroup(PKG_O, UID_O, group, fromTargetApp);
+ mHelper.createNotificationChannelGroup(PKG_O, UID_O, group, fromTargetApp,
+ UID_O, false);
}
try {
NotificationChannelGroup group = new NotificationChannelGroup(
String.valueOf(NOTIFICATION_CHANNEL_GROUP_COUNT_LIMIT),
String.valueOf(NOTIFICATION_CHANNEL_GROUP_COUNT_LIMIT));
- mHelper.createNotificationChannelGroup(PKG_O, UID_O, group, fromTargetApp);
+ mHelper.createNotificationChannelGroup(PKG_O, UID_O, group, fromTargetApp,
+ UID_O, false);
fail("Allowed to create too many notification channel groups");
} catch (IllegalStateException e) {
// great
@@ -4222,7 +4419,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
for (int i = 0; i < NOTIFICATION_CHANNEL_GROUP_COUNT_LIMIT; i++) {
NotificationChannelGroup group = new NotificationChannelGroup(String.valueOf(i),
String.valueOf(i));
- mHelper.createNotificationChannelGroup(PKG_O, UID_O, group, true);
+ mHelper.createNotificationChannelGroup(PKG_O, UID_O, group, true,
+ UID_O, false);
}
final String xml = "<ranking version=\"1\">\n"
@@ -4300,13 +4498,15 @@ public class PreferencesHelperTest extends UiServiceTestCase {
NotificationChannel parent =
new NotificationChannel("parent", "messages", IMPORTANCE_DEFAULT);
- mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false,
+ UID_O, false);
NotificationChannel friend = new NotificationChannel(String.format(
CONVERSATION_CHANNEL_ID_FORMAT, parent.getId(), conversationId),
"messages", IMPORTANCE_DEFAULT);
friend.setConversationId(parent.getId(), conversationId);
- mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false,
+ UID_O, false);
compareChannelsParentChild(parent, mHelper.getConversationNotificationChannel(
PKG_O, UID_O, parent.getId(), conversationId, false, false), conversationId);
@@ -4318,7 +4518,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
NotificationChannel parent =
new NotificationChannel("parent", "messages", IMPORTANCE_DEFAULT);
- mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false,
+ UID_O, false);
compareChannels(parent, mHelper.getConversationNotificationChannel(
PKG_O, UID_O, parent.getId(), conversationId, true, false));
@@ -4335,7 +4536,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
friend.setConversationId(parentId, conversationId);
try {
- mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false,
+ UID_O, false);
fail("allowed creation of conversation channel without a parent");
} catch (IllegalArgumentException e) {
// good
@@ -4429,9 +4631,12 @@ public class PreferencesHelperTest extends UiServiceTestCase {
mAppOpsManager, mStatsEventBuilderFactory, false);
mHelper.createNotificationChannel(
- PKG_P, UID_P, new NotificationChannel("id", "id", 2), true, false);
- assertTrue(mHelper.deleteNotificationChannel(PKG_P, UID_P, "id"));
- assertFalse(mHelper.deleteNotificationChannel(PKG_P, UID_P, "id"));
+ PKG_P, UID_P, new NotificationChannel("id", "id", 2), true, false,
+ UID_P, false);
+ assertTrue(mHelper.deleteNotificationChannel(PKG_P, UID_P, "id",
+ UID_P, false));
+ assertFalse(mHelper.deleteNotificationChannel(PKG_P, UID_P, "id",
+ UID_P, false));
}
@Test
@@ -4441,8 +4646,9 @@ public class PreferencesHelperTest extends UiServiceTestCase {
mAppOpsManager, mStatsEventBuilderFactory, false);
mHelper.createNotificationChannel(
- PKG_P, UID_P, new NotificationChannel("id", "id", 2), true, false);
- mHelper.deleteNotificationChannel(PKG_P, UID_P, "id");
+ PKG_P, UID_P, new NotificationChannel("id", "id", 2), true, false,
+ UID_P, false);
+ mHelper.deleteNotificationChannel(PKG_P, UID_P, "id", UID_P, false);
NotificationChannel nc1 = mHelper.getNotificationChannel(PKG_P, UID_P, "id", true);
assertTrue(DateUtils.isToday(nc1.getDeletedTimeMs()));
assertTrue(nc1.isDeleted());
@@ -4471,14 +4677,16 @@ public class PreferencesHelperTest extends UiServiceTestCase {
mAppOpsManager, mStatsEventBuilderFactory, false);
mHelper.createNotificationChannel(
- PKG_P, UID_P, new NotificationChannel("id", "id", 2), true, false);
- mHelper.deleteNotificationChannel(PKG_P, UID_P, "id");
+ PKG_P, UID_P, new NotificationChannel("id", "id", 2), true, false,
+ UID_P, false);
+ mHelper.deleteNotificationChannel(PKG_P, UID_P, "id", UID_P, false);
NotificationChannel nc1 = mHelper.getNotificationChannel(PKG_P, UID_P, "id", true);
assertTrue(DateUtils.isToday(nc1.getDeletedTimeMs()));
assertTrue(nc1.isDeleted());
mHelper.createNotificationChannel(
- PKG_P, UID_P, new NotificationChannel("id", "id", 2), true, false);
+ PKG_P, UID_P, new NotificationChannel("id", "id", 2), true, false,
+ UID_P, false);
nc1 = mHelper.getNotificationChannel(PKG_P, UID_P, "id", true);
assertEquals(-1, nc1.getDeletedTimeMs());
assertFalse(nc1.isDeleted());
@@ -4513,29 +4721,35 @@ public class PreferencesHelperTest extends UiServiceTestCase {
String convoId = "convo";
NotificationChannel messages =
new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
- mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false,
+ UID_O, false);
NotificationChannel calls =
new NotificationChannel("calls", "Calls", IMPORTANCE_DEFAULT);
- mHelper.createNotificationChannel(PKG_O, UID_O, calls, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, calls, true, false,
+ UID_O, false);
NotificationChannel p =
new NotificationChannel("p calls", "Calls", IMPORTANCE_DEFAULT);
- mHelper.createNotificationChannel(PKG_P, UID_P, p, true, false);
+ mHelper.createNotificationChannel(PKG_P, UID_P, p, true, false,
+ UID_P, false);
NotificationChannel channel =
new NotificationChannel("A person msgs", "messages from A", IMPORTANCE_DEFAULT);
channel.setConversationId(messages.getId(), convoId);
- mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false,
+ UID_O, false);
NotificationChannel diffConvo =
new NotificationChannel("B person msgs", "messages from B", IMPORTANCE_DEFAULT);
diffConvo.setConversationId(p.getId(), "different convo");
- mHelper.createNotificationChannel(PKG_P, UID_P, diffConvo, true, false);
+ mHelper.createNotificationChannel(PKG_P, UID_P, diffConvo, true, false,
+ UID_O, false);
NotificationChannel channel2 =
new NotificationChannel("A person calls", "calls from A", IMPORTANCE_DEFAULT);
channel2.setConversationId(calls.getId(), convoId);
channel2.setImportantConversation(true);
- mHelper.createNotificationChannel(PKG_O, UID_O, channel2, false, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, channel2, false, false,
+ SYSTEM_UID, true);
List<ConversationChannelWrapper> convos =
mHelper.getConversations(IntArray.wrap(new int[] {0}), false);
@@ -4551,23 +4765,26 @@ public class PreferencesHelperTest extends UiServiceTestCase {
String convoId = "convo";
NotificationChannel messages =
new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
- mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false,
+ UID_O, false);
NotificationChannel messagesUser10 =
new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
mHelper.createNotificationChannel(
- PKG_O, UID_O + UserHandle.PER_USER_RANGE, messagesUser10, true, false);
+ PKG_O, UID_O + UserHandle.PER_USER_RANGE, messagesUser10, true, false,
+ UID_O + UserHandle.PER_USER_RANGE, false);
NotificationChannel messagesFromB =
new NotificationChannel("B person msgs", "messages from B", IMPORTANCE_DEFAULT);
messagesFromB.setConversationId(messages.getId(), "different convo");
- mHelper.createNotificationChannel(PKG_O, UID_O, messagesFromB, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, messagesFromB, true, false, UID_O, false);
NotificationChannel messagesFromBUser10 =
new NotificationChannel("B person msgs", "messages from B", IMPORTANCE_DEFAULT);
messagesFromBUser10.setConversationId(messagesUser10.getId(), "different convo");
mHelper.createNotificationChannel(
- PKG_O, UID_O + UserHandle.PER_USER_RANGE, messagesFromBUser10, true, false);
+ PKG_O, UID_O + UserHandle.PER_USER_RANGE, messagesFromBUser10, true, false,
+ UID_O + UserHandle.PER_USER_RANGE, false);
List<ConversationChannelWrapper> convos =
@@ -4589,30 +4806,31 @@ public class PreferencesHelperTest extends UiServiceTestCase {
String convoId = "convo";
NotificationChannel messages =
new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
- mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false, UID_O, false);
NotificationChannel calls =
new NotificationChannel("calls", "Calls", IMPORTANCE_DEFAULT);
- mHelper.createNotificationChannel(PKG_O, UID_O, calls, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, calls, true, false, UID_O, false);
NotificationChannel p =
new NotificationChannel("p calls", "Calls", IMPORTANCE_DEFAULT);
- mHelper.createNotificationChannel(PKG_P, UID_P, p, true, false);
+ mHelper.createNotificationChannel(PKG_P, UID_P, p, true, false, UID_O, false);
NotificationChannel channel =
new NotificationChannel("A person msgs", "messages from A", IMPORTANCE_DEFAULT);
channel.setConversationId(messages.getId(), convoId);
- mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false, UID_O, false);
NotificationChannel diffConvo =
new NotificationChannel("B person msgs", "messages from B", IMPORTANCE_DEFAULT);
diffConvo.setConversationId(p.getId(), "different convo");
diffConvo.setDemoted(true);
- mHelper.createNotificationChannel(PKG_P, UID_P, diffConvo, true, false);
+ mHelper.createNotificationChannel(PKG_P, UID_P, diffConvo, true, false, UID_P, false);
NotificationChannel channel2 =
new NotificationChannel("A person calls", "calls from A", IMPORTANCE_DEFAULT);
channel2.setConversationId(calls.getId(), convoId);
channel2.setImportantConversation(true);
- mHelper.createNotificationChannel(PKG_O, UID_O, channel2, false, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, channel2, false, false,
+ SYSTEM_UID, true);
List<ConversationChannelWrapper> convos =
mHelper.getConversations(IntArray.wrap(new int[] {0}), false);
@@ -4628,30 +4846,31 @@ public class PreferencesHelperTest extends UiServiceTestCase {
String convoId = "convo";
NotificationChannel messages =
new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
- mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false, UID_O, false);
NotificationChannel calls =
new NotificationChannel("calls", "Calls", IMPORTANCE_DEFAULT);
- mHelper.createNotificationChannel(PKG_O, UID_O, calls, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, calls, true, false, UID_O, false);
NotificationChannel p =
new NotificationChannel("p calls", "Calls", IMPORTANCE_DEFAULT);
- mHelper.createNotificationChannel(PKG_P, UID_P, p, true, false);
+ mHelper.createNotificationChannel(PKG_P, UID_P, p, true, false, UID_P, false);
NotificationChannel channel =
new NotificationChannel("A person msgs", "messages from A", IMPORTANCE_DEFAULT);
channel.setConversationId(messages.getId(), convoId);
channel.setImportantConversation(true);
- mHelper.createNotificationChannel(PKG_O, UID_O, channel, false, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, channel, false, false, UID_O, false);
NotificationChannel diffConvo =
new NotificationChannel("B person msgs", "messages from B", IMPORTANCE_DEFAULT);
diffConvo.setConversationId(p.getId(), "different convo");
diffConvo.setImportantConversation(true);
- mHelper.createNotificationChannel(PKG_P, UID_P, diffConvo, false, false);
+ mHelper.createNotificationChannel(PKG_P, UID_P, diffConvo, false, false,
+ SYSTEM_UID, true);
NotificationChannel channel2 =
new NotificationChannel("A person calls", "calls from A", IMPORTANCE_DEFAULT);
channel2.setConversationId(calls.getId(), convoId);
- mHelper.createNotificationChannel(PKG_O, UID_O, channel2, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, channel2, true, false, UID_O, false);
List<ConversationChannelWrapper> convos =
mHelper.getConversations(IntArray.wrap(new int[] {0}), true);
@@ -4667,13 +4886,14 @@ public class PreferencesHelperTest extends UiServiceTestCase {
String convoId = "convo";
NotificationChannel messages =
new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
- mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false, UID_O, false);
NotificationChannel channel =
new NotificationChannel("A person msgs", "messages from A", IMPORTANCE_DEFAULT);
channel.setConversationId(messages.getId(), convoId);
channel.setImportantConversation(true);
- mHelper.createNotificationChannel(PKG_O, UID_O, channel, false, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, channel, false, false,
+ SYSTEM_UID, true);
mHelper.permanentlyDeleteNotificationChannel(PKG_O, UID_O, "messages");
@@ -4704,7 +4924,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
public void testGetConversations_noConversations() {
NotificationChannel channel =
new NotificationChannel("not_convo", "not_convo", IMPORTANCE_DEFAULT);
- mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false, UID_O, false);
assertThat(mHelper.getConversations(PKG_O, UID_O)).isEmpty();
}
@@ -4713,15 +4933,15 @@ public class PreferencesHelperTest extends UiServiceTestCase {
public void testGetConversations_noDisabledGroups() {
NotificationChannelGroup group = new NotificationChannelGroup("a", "a");
group.setBlocked(true);
- mHelper.createNotificationChannelGroup(PKG_O, UID_O, group, false);
+ mHelper.createNotificationChannelGroup(PKG_O, UID_O, group, false, SYSTEM_UID, true);
NotificationChannel parent = new NotificationChannel("parent", "p", 1);
- mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false, UID_O, false);
NotificationChannel channel =
new NotificationChannel("convo", "convo", IMPORTANCE_DEFAULT);
channel.setConversationId("parent", "convo");
channel.setGroup(group.getId());
- mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false, UID_O, false);
assertThat(mHelper.getConversations(PKG_O, UID_O)).isEmpty();
}
@@ -4729,12 +4949,12 @@ public class PreferencesHelperTest extends UiServiceTestCase {
@Test
public void testGetConversations_noDeleted() {
NotificationChannel parent = new NotificationChannel("parent", "p", 1);
- mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false, UID_O, false);
NotificationChannel channel =
new NotificationChannel("convo", "convo", IMPORTANCE_DEFAULT);
channel.setConversationId("parent", "convo");
- mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
- mHelper.deleteNotificationChannel(PKG_O, UID_O, channel.getId());
+ mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false, UID_O, false);
+ mHelper.deleteNotificationChannel(PKG_O, UID_O, channel.getId(), UID_O, false);
assertThat(mHelper.getConversations(PKG_O, UID_O)).isEmpty();
}
@@ -4742,12 +4962,12 @@ public class PreferencesHelperTest extends UiServiceTestCase {
@Test
public void testGetConversations_noDemoted() {
NotificationChannel parent = new NotificationChannel("parent", "p", 1);
- mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false, UID_O, false);
NotificationChannel channel =
new NotificationChannel("convo", "convo", IMPORTANCE_DEFAULT);
channel.setConversationId("parent", "convo");
channel.setDemoted(true);
- mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false, UID_O, false);
assertThat(mHelper.getConversations(PKG_O, UID_O)).isEmpty();
}
@@ -4755,26 +4975,26 @@ public class PreferencesHelperTest extends UiServiceTestCase {
@Test
public void testGetConversations() {
NotificationChannelGroup group = new NotificationChannelGroup("acct", "account_name");
- mHelper.createNotificationChannelGroup(PKG_O, UID_O, group, true);
+ mHelper.createNotificationChannelGroup(PKG_O, UID_O, group, true, UID_O, false);
NotificationChannel messages =
new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
messages.setGroup(group.getId());
- mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false, UID_O, false);
NotificationChannel calls =
new NotificationChannel("calls", "Calls", IMPORTANCE_HIGH);
- mHelper.createNotificationChannel(PKG_O, UID_O, calls, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, calls, true, false, UID_O, false);
NotificationChannel channel =
new NotificationChannel("A person", "A lovely person", IMPORTANCE_DEFAULT);
channel.setGroup(group.getId());
channel.setConversationId(messages.getId(), channel.getName().toString());
- mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false, UID_O, false);
NotificationChannel channel2 =
new NotificationChannel("B person", "B fabulous person", IMPORTANCE_DEFAULT);
channel2.setConversationId(calls.getId(), channel2.getName().toString());
- mHelper.createNotificationChannel(PKG_O, UID_O, channel2, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, channel2, true, false, UID_O, false);
Map<String, NotificationChannel> expected = new HashMap<>();
expected.put(channel.getId(), channel);
@@ -4807,35 +5027,36 @@ public class PreferencesHelperTest extends UiServiceTestCase {
String convoIdC = "convoC";
NotificationChannel messages =
new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
- mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false, UID_O, false);
NotificationChannel calls =
new NotificationChannel("calls", "Calls", IMPORTANCE_DEFAULT);
- mHelper.createNotificationChannel(PKG_O, UID_O, calls, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, calls, true, false, UID_O, false);
NotificationChannel channel =
new NotificationChannel("A person msgs", "messages from A", IMPORTANCE_DEFAULT);
channel.setConversationId(messages.getId(), convoId);
- mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false, UID_O, false);
NotificationChannel noMatch =
new NotificationChannel("B person msgs", "messages from B", IMPORTANCE_DEFAULT);
noMatch.setConversationId(messages.getId(), "different convo");
- mHelper.createNotificationChannel(PKG_O, UID_O, noMatch, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, noMatch, true, false, UID_O, false);
NotificationChannel channel2 =
new NotificationChannel("A person calls", "calls from A", IMPORTANCE_DEFAULT);
channel2.setConversationId(calls.getId(), convoId);
- mHelper.createNotificationChannel(PKG_O, UID_O, channel2, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, channel2, true, false, UID_O, false);
NotificationChannel channel3 =
new NotificationChannel("C person msgs", "msgs from C", IMPORTANCE_DEFAULT);
channel3.setConversationId(messages.getId(), convoIdC);
- mHelper.createNotificationChannel(PKG_O, UID_O, channel3, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, channel3, true, false, UID_O, false);
assertEquals(channel, mHelper.getNotificationChannel(PKG_O, UID_O, channel.getId(), false));
assertEquals(channel2,
mHelper.getNotificationChannel(PKG_O, UID_O, channel2.getId(), false));
- List<String> deleted = mHelper.deleteConversations(PKG_O, UID_O, Set.of(convoId, convoIdC));
+ List<String> deleted = mHelper.deleteConversations(PKG_O, UID_O, Set.of(convoId, convoIdC),
+ UID_O, false);
assertEquals(3, deleted.size());
assertEquals(messages,
@@ -4950,12 +5171,12 @@ public class PreferencesHelperTest extends UiServiceTestCase {
String channelId = "parent";
String name = "messages";
NotificationChannel fodderA = new NotificationChannel("a", "a", IMPORTANCE_LOW);
- mHelper.createNotificationChannel(PKG_O, UID_O, fodderA, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, fodderA, true, false, UID_O, false);
NotificationChannel channel =
new NotificationChannel(channelId, name, IMPORTANCE_DEFAULT);
- mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false, UID_O, false);
NotificationChannel fodderB = new NotificationChannel("b", "b", IMPORTANCE_HIGH);
- mHelper.createNotificationChannel(PKG_O, UID_O, fodderB, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, fodderB, true, false, UID_O, false);
ArrayList<StatsEvent> events = new ArrayList<>();
mHelper.pullPackageChannelPreferencesStats(events);
@@ -4980,11 +5201,11 @@ public class PreferencesHelperTest extends UiServiceTestCase {
@Test
public void testPullPackageChannelPreferencesStats_one_to_one() {
NotificationChannel channelA = new NotificationChannel("a", "a", IMPORTANCE_LOW);
- mHelper.createNotificationChannel(PKG_O, UID_O, channelA, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, channelA, true, false, UID_O, false);
NotificationChannel channelB = new NotificationChannel("b", "b", IMPORTANCE_LOW);
- mHelper.createNotificationChannel(PKG_O, UID_O, channelB, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, channelB, true, false, UID_O, false);
NotificationChannel channelC = new NotificationChannel("c", "c", IMPORTANCE_HIGH);
- mHelper.createNotificationChannel(PKG_O, UID_O, channelC, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, channelC, true, false, UID_O, false);
List<String> channels = new LinkedList<>(Arrays.asList("a", "b", "c"));
@@ -5008,7 +5229,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
NotificationChannel parent =
new NotificationChannel("parent", "messages", IMPORTANCE_DEFAULT);
- mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false, UID_O, false);
String channelId = String.format(
CONVERSATION_CHANNEL_ID_FORMAT, parent.getId(), conversationId);
@@ -5016,7 +5237,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
NotificationChannel friend = new NotificationChannel(channelId,
name, IMPORTANCE_DEFAULT);
friend.setConversationId(parent.getId(), conversationId);
- mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false, UID_O, false);
ArrayList<StatsEvent> events = new ArrayList<>();
mHelper.pullPackageChannelPreferencesStats(events);
@@ -5038,14 +5259,14 @@ public class PreferencesHelperTest extends UiServiceTestCase {
public void testPullPackageChannelPreferencesStats_conversation_demoted() {
NotificationChannel parent =
new NotificationChannel("parent", "messages", IMPORTANCE_DEFAULT);
- mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false, UID_O, false);
String channelId = String.format(
CONVERSATION_CHANNEL_ID_FORMAT, parent.getId(), "friend");
NotificationChannel friend = new NotificationChannel(channelId,
"conversation", IMPORTANCE_DEFAULT);
friend.setConversationId(parent.getId(), "friend");
friend.setDemoted(true);
- mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false, UID_O, false);
ArrayList<StatsEvent> events = new ArrayList<>();
mHelper.pullPackageChannelPreferencesStats(events);
@@ -5067,14 +5288,14 @@ public class PreferencesHelperTest extends UiServiceTestCase {
public void testPullPackageChannelPreferencesStats_conversation_priority() {
NotificationChannel parent =
new NotificationChannel("parent", "messages", IMPORTANCE_DEFAULT);
- mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false, UID_O, false);
String channelId = String.format(
CONVERSATION_CHANNEL_ID_FORMAT, parent.getId(), "friend");
NotificationChannel friend = new NotificationChannel(channelId,
"conversation", IMPORTANCE_DEFAULT);
friend.setConversationId(parent.getId(), "friend");
friend.setImportantConversation(true);
- mHelper.createNotificationChannel(PKG_O, UID_O, friend, false, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, friend, false, false, SYSTEM_UID, true);
ArrayList<StatsEvent> events = new ArrayList<>();
mHelper.pullPackageChannelPreferencesStats(events);
@@ -5096,11 +5317,12 @@ public class PreferencesHelperTest extends UiServiceTestCase {
public void testPullPackagePreferencesStats_postPermissionMigration() {
// make sure there's at least one channel for each package we want to test
NotificationChannel channelA = new NotificationChannel("a", "a", IMPORTANCE_DEFAULT);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channelA, true, false);
+ mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channelA, true, false,
+ UID_N_MR1, false);
NotificationChannel channelB = new NotificationChannel("b", "b", IMPORTANCE_DEFAULT);
- mHelper.createNotificationChannel(PKG_O, UID_O, channelB, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, channelB, true, false, UID_O, false);
NotificationChannel channelC = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT);
- mHelper.createNotificationChannel(PKG_P, UID_P, channelC, true, false);
+ mHelper.createNotificationChannel(PKG_P, UID_P, channelC, true, false, UID_P, false);
// build a collection of app permissions that should be passed in and used
ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> appPermissions = new ArrayMap<>();
@@ -5143,7 +5365,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
@Test
public void testUnlockNotificationChannelImportance() {
NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_LOW);
- mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false, UID_O, false);
channel.lockFields(USER_LOCKED_IMPORTANCE);
assertTrue((channel.getUserLockedFields() & USER_LOCKED_IMPORTANCE) != 0);
@@ -5155,11 +5377,11 @@ public class PreferencesHelperTest extends UiServiceTestCase {
@Test
public void testUnlockAllNotificationChannels() {
NotificationChannel channelA = new NotificationChannel("a", "a", IMPORTANCE_LOW);
- mHelper.createNotificationChannel(PKG_O, UID_O, channelA, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, channelA, true, false, UID_O, false);
NotificationChannel channelB = new NotificationChannel("b", "b", IMPORTANCE_DEFAULT);
- mHelper.createNotificationChannel(PKG_P, UID_P, channelB, true, false);
+ mHelper.createNotificationChannel(PKG_P, UID_P, channelB, true, false, UID_P, false);
NotificationChannel channelC = new NotificationChannel("c", "c", IMPORTANCE_HIGH);
- mHelper.createNotificationChannel(PKG_P, UID_O, channelC, false, false);
+ mHelper.createNotificationChannel(PKG_P, UID_O, channelC, false, false, UID_O, false);
channelA.lockFields(USER_LOCKED_IMPORTANCE);
channelB.lockFields(USER_LOCKED_IMPORTANCE);
@@ -5178,11 +5400,11 @@ public class PreferencesHelperTest extends UiServiceTestCase {
@Test
public void createNotificationChannel_updateDifferent_requestsSort() {
NotificationChannel original = new NotificationChannel("id", "Bah", IMPORTANCE_DEFAULT);
- mHelper.createNotificationChannel(PKG_P, 0, original, true, false);
+ mHelper.createNotificationChannel(PKG_P, 0, original, true, false, 0, false);
clearInvocations(mHandler);
NotificationChannel updated = new NotificationChannel("id", "Wow", IMPORTANCE_DEFAULT);
- mHelper.createNotificationChannel(PKG_P, 0, updated, true, false);
+ mHelper.createNotificationChannel(PKG_P, 0, updated, true, false, 0, false);
verify(mHandler).requestSort();
}
@@ -5190,11 +5412,11 @@ public class PreferencesHelperTest extends UiServiceTestCase {
@Test
public void createNotificationChannel_updateSame_doesNotRequestSort() {
NotificationChannel original = new NotificationChannel("id", "Bah", IMPORTANCE_DEFAULT);
- mHelper.createNotificationChannel(PKG_P, 0, original, true, false);
+ mHelper.createNotificationChannel(PKG_P, 0, original, true, false, 0, false);
clearInvocations(mHandler);
NotificationChannel same = new NotificationChannel("id", "Bah", IMPORTANCE_DEFAULT);
- mHelper.createNotificationChannel(PKG_P, 0, same, true, false);
+ mHelper.createNotificationChannel(PKG_P, 0, same, true, false, 0, false);
verifyZeroInteractions(mHandler);
}
@@ -5202,11 +5424,11 @@ public class PreferencesHelperTest extends UiServiceTestCase {
@Test
public void updateNotificationChannel_different_requestsSort() {
NotificationChannel original = new NotificationChannel("id", "Bah", IMPORTANCE_DEFAULT);
- mHelper.createNotificationChannel(PKG_P, 0, original, true, false);
+ mHelper.createNotificationChannel(PKG_P, 0, original, true, false, 0, false);
clearInvocations(mHandler);
NotificationChannel updated = new NotificationChannel("id", "Wow", IMPORTANCE_DEFAULT);
- mHelper.updateNotificationChannel(PKG_P, 0, updated, false);
+ mHelper.updateNotificationChannel(PKG_P, 0, updated, false, 0, false);
verify(mHandler).requestSort();
}
@@ -5214,7 +5436,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
@Test
public void updateNotificationChannel_same_doesNotRequestSort() {
NotificationChannel original = new NotificationChannel("id", "Bah", IMPORTANCE_DEFAULT);
- mHelper.createNotificationChannel(PKG_P, 0, original, true, false);
+ mHelper.createNotificationChannel(PKG_P, 0, original, true, false, 0, false);
clearInvocations(mHandler);
// Note: Creating a NotificationChannel identical to the original is not equals(), because
// of mOriginalImportance. So we create a "true copy" instead.
@@ -5224,7 +5446,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
NotificationChannel same = NotificationChannel.CREATOR.createFromParcel(parcel);
parcel.recycle();
- mHelper.updateNotificationChannel(PKG_P, 0, same, false);
+ mHelper.updateNotificationChannel(PKG_P, 0, same, false, 0, false);
verifyZeroInteractions(mHandler);
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/TestableNotificationManagerService.java b/services/tests/uiservicestests/src/com/android/server/notification/TestableNotificationManagerService.java
index 61a6985d473e..9f4eee7e332f 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/TestableNotificationManagerService.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/TestableNotificationManagerService.java
@@ -67,7 +67,13 @@ public class TestableNotificationManagerService extends NotificationManagerServi
@Override
protected boolean isCallerSystemOrPhone() {
countSystemChecks++;
- return isSystemUid;
+ return isSystemUid || isSystemAppId;
+ }
+
+ @Override
+ protected boolean isCallerIsSystemOrSystemUi() {
+ countSystemChecks++;
+ return isSystemUid || isSystemAppId;
}
@Override
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeEventLoggerFake.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeEventLoggerFake.java
new file mode 100644
index 000000000000..4a1435f9ee64
--- /dev/null
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeEventLoggerFake.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.notification;
+
+import android.content.pm.PackageManager;
+
+import com.android.os.dnd.DNDPolicyProto;
+
+import com.google.protobuf.InvalidProtocolBufferException;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * ZenModeEventLoggerFake extends ZenModeEventLogger for ease of verifying logging output. This
+ * class behaves exactly the same as its parent class except that instead of actually logging, it
+ * stores the full information at time of log whenever something would be logged.
+ */
+public class ZenModeEventLoggerFake extends ZenModeEventLogger {
+ // A record of the contents of each event we'd log, stored by recording the ChangeState object
+ // at the time of the log.
+ private List<ZenStateChanges> mChanges = new ArrayList<>();
+
+ public ZenModeEventLoggerFake(PackageManager pm) {
+ super(pm);
+ }
+
+ @Override
+ void logChanges() {
+ // current change state being logged
+ mChanges.add(mChangeState.copy());
+ }
+
+ // Reset the state of the logger (remove all changes).
+ public void reset() {
+ mChanges = new ArrayList<>();
+ }
+
+ // Returns the number of changes logged.
+ public int numLoggedChanges() {
+ return mChanges.size();
+ }
+
+ // is index i out of range for the set of changes we have
+ private boolean outOfRange(int i) {
+ return i < 0 || i >= mChanges.size();
+ }
+
+ // Throw an exception if provided index is out of range
+ private void checkInRange(int i) throws IllegalArgumentException {
+ if (outOfRange(i)) {
+ throw new IllegalArgumentException("invalid index for logged event: " + i);
+ }
+ }
+
+ // Get the UiEvent ID of the i'th logged event.
+ public int getEventId(int i) throws IllegalArgumentException {
+ checkInRange(i);
+ return mChanges.get(i).getEventId().getId();
+ }
+
+ // Get the previous zen mode associated with the change at event i.
+ public int getPrevZenMode(int i) throws IllegalArgumentException {
+ checkInRange(i);
+ return mChanges.get(i).mPrevZenMode;
+ }
+
+ // Get the new zen mode associated with the change at event i.
+ public int getNewZenMode(int i) throws IllegalArgumentException {
+ checkInRange(i);
+ return mChanges.get(i).mNewZenMode;
+ }
+
+ // Get the changed rule type associated with event i.
+ public int getChangedRuleType(int i) throws IllegalArgumentException {
+ checkInRange(i);
+ return mChanges.get(i).getChangedRuleType();
+ }
+
+ public int getNumRulesActive(int i) throws IllegalArgumentException {
+ checkInRange(i);
+ return mChanges.get(i).getNumRulesActive();
+ }
+
+ public boolean getFromSystemOrSystemUi(int i) throws IllegalArgumentException {
+ // While this isn't a logged output value, it's still helpful to check in tests.
+ checkInRange(i);
+ return mChanges.get(i).mFromSystemOrSystemUi;
+ }
+
+ public boolean getIsUserAction(int i) throws IllegalArgumentException {
+ checkInRange(i);
+ return mChanges.get(i).getIsUserAction();
+ }
+
+ public int getPackageUid(int i) throws IllegalArgumentException {
+ checkInRange(i);
+ return mChanges.get(i).getPackageUid();
+ }
+
+ // Get the DNDPolicyProto (unmarshaled from bytes) associated with event i.
+ // Note that in creation of the log, we use a notification.proto mirror of DNDPolicyProto,
+ // but here we use the actual logging-side proto to make sure they continue to match.
+ public DNDPolicyProto getPolicyProto(int i) throws IllegalArgumentException {
+ checkInRange(i);
+ byte[] policyBytes = mChanges.get(i).getDNDPolicyProto();
+ try {
+ return DNDPolicyProto.parseFrom(policyBytes);
+ } catch (InvalidProtocolBufferException e) {
+ return null; // couldn't turn it into proto
+ }
+ }
+
+ public boolean getAreChannelsBypassing(int i) throws IllegalArgumentException {
+ checkInRange(i);
+ return mChanges.get(i).getAreChannelsBypassing();
+ }
+}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
index 2c95bdee3454..dedb8f170ee0 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
@@ -34,16 +34,21 @@ import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_FULL_SCRE
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_LIGHTS;
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK;
import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+import static android.service.notification.Condition.STATE_FALSE;
import static android.service.notification.Condition.STATE_TRUE;
import static android.util.StatsLog.ANNOTATION_ID_IS_UID;
+import static com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags.LOG_DND_STATE_EVENTS;
import static com.android.internal.util.FrameworkStatsLog.DND_MODE_RULE;
import static com.android.os.dnd.DNDModeProto.CHANNELS_BYPASSING_FIELD_NUMBER;
import static com.android.os.dnd.DNDModeProto.ENABLED_FIELD_NUMBER;
import static com.android.os.dnd.DNDModeProto.ID_FIELD_NUMBER;
import static com.android.os.dnd.DNDModeProto.UID_FIELD_NUMBER;
import static com.android.os.dnd.DNDModeProto.ZEN_MODE_FIELD_NUMBER;
+import static com.android.os.dnd.DNDProtoEnums.PEOPLE_STARRED;
import static com.android.os.dnd.DNDProtoEnums.ROOT_CONFIG;
+import static com.android.os.dnd.DNDProtoEnums.STATE_ALLOW;
+import static com.android.os.dnd.DNDProtoEnums.STATE_DISALLOW;
import static com.android.server.notification.ZenModeHelper.RULE_LIMIT_PER_PACKAGE;
import static junit.framework.Assert.assertEquals;
@@ -104,9 +109,12 @@ import android.util.StatsEvent;
import android.util.Xml;
import com.android.internal.R;
+import com.android.internal.config.sysui.TestableFlagResolver;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.modules.utils.TypedXmlPullParser;
import com.android.modules.utils.TypedXmlSerializer;
+import com.android.os.dnd.DNDPolicyProto;
+import com.android.os.dnd.DNDProtoEnums;
import com.android.server.UiServiceTestCase;
import com.android.server.notification.ManagedServices.UserProfiles;
@@ -152,6 +160,8 @@ public class ZenModeHelperTest extends UiServiceTestCase {
private ContentResolver mContentResolver;
@Mock AppOpsManager mAppOps;
private WrappedSysUiStatsEvent.WrappedBuilderFactory mStatsEventBuilderFactory;
+ TestableFlagResolver mTestFlagResolver = new TestableFlagResolver();
+ ZenModeEventLoggerFake mZenModeEventLogger;
@Before
public void setUp() throws PackageManager.NameNotFoundException {
@@ -176,8 +186,10 @@ public class ZenModeHelperTest extends UiServiceTestCase {
AppGlobals.getPackageManager());
mConditionProviders.addSystemProvider(new CountdownConditionProvider());
mConditionProviders.addSystemProvider(new ScheduleConditionProvider());
+ mZenModeEventLogger = new ZenModeEventLoggerFake(mPackageManager);
mZenModeHelper = new ZenModeHelper(mContext, mTestableLooper.getLooper(),
- mConditionProviders, mStatsEventBuilderFactory);
+ mConditionProviders, mStatsEventBuilderFactory, mTestFlagResolver,
+ mZenModeEventLogger);
ResolveInfo ri = new ResolveInfo();
ri.activityInfo = new ActivityInfo();
@@ -188,6 +200,8 @@ public class ZenModeHelperTest extends UiServiceTestCase {
when(mPackageManager.getPackagesForUid(anyInt())).thenReturn(
new String[] {pkg});
mZenModeHelper.mPm = mPackageManager;
+
+ mZenModeEventLogger.reset();
}
private XmlResourceParser getDefaultConfigParser() throws IOException, XmlPullParserException {
@@ -224,7 +238,8 @@ public class ZenModeHelperTest extends UiServiceTestCase {
mZenModeHelper.writeXml(serializer, false, version, UserHandle.USER_ALL);
serializer.endDocument();
serializer.flush();
- mZenModeHelper.setConfig(new ZenModeConfig(), null, "writing xml");
+ mZenModeHelper.setConfig(new ZenModeConfig(), null, "writing xml", Process.SYSTEM_UID,
+ true);
return baos;
}
@@ -239,7 +254,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
serializer.flush();
ZenModeConfig newConfig = new ZenModeConfig();
newConfig.user = userId;
- mZenModeHelper.setConfig(newConfig, null, "writing xml");
+ mZenModeHelper.setConfig(newConfig, null, "writing xml", Process.SYSTEM_UID, true);
return baos;
}
@@ -822,14 +837,11 @@ public class ZenModeHelperTest extends UiServiceTestCase {
mZenModeHelper.mAudioManager = mAudioManager;
setupZenConfig();
- // Change the config a little bit, but enough that it would turn zen mode on
- ZenModeConfig newConfig = mZenModeHelper.mConfig.copy();
- newConfig.manualRule = new ZenModeConfig.ZenRule();
- newConfig.manualRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
- newConfig.manualRule.enabled = true;
- mZenModeHelper.setConfig(newConfig, null, "test");
+ // Turn manual zen mode on
+ mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, null,
+ "test", CUSTOM_PKG_UID, false);
- // audio manager shouldn't do anything until the handler processes its messagse
+ // audio manager shouldn't do anything until the handler processes its messages
verify(mAudioManager, never()).updateRingerModeAffectedStreamsInternal();
// now process the looper's messages
@@ -993,7 +1005,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
List<StatsEvent> events = new LinkedList<>();
mZenModeHelper.pullRules(events);
- mZenModeHelper.removeAutomaticZenRule(CUSTOM_RULE_ID, "test");
+ mZenModeHelper.removeAutomaticZenRule(CUSTOM_RULE_ID, "test", CUSTOM_PKG_UID, false);
assertTrue(-1
== mZenModeHelper.mRulesUidCache.getOrDefault(CUSTOM_PKG_NAME + "|" + 0, -1));
}
@@ -1044,12 +1056,12 @@ public class ZenModeHelperTest extends UiServiceTestCase {
config10.user = 10;
config10.allowAlarms = true;
config10.allowMedia = true;
- mZenModeHelper.setConfig(config10, null, "writeXml");
+ mZenModeHelper.setConfig(config10, null, "writeXml", Process.SYSTEM_UID, true);
ZenModeConfig config11 = mZenModeHelper.mConfig.copy();
config11.user = 11;
config11.allowAlarms = false;
config11.allowMedia = false;
- mZenModeHelper.setConfig(config11, null, "writeXml");
+ mZenModeHelper.setConfig(config11, null, "writeXml", Process.SYSTEM_UID, true);
// Backup user 10 and reset values.
ByteArrayOutputStream baos = writeXmlAndPurgeForUser(null, 10);
@@ -1552,7 +1564,8 @@ public class ZenModeHelperTest extends UiServiceTestCase {
ZenModeConfig config = new ZenModeConfig();
config.automaticRules = new ArrayMap<>();
mZenModeHelper.mConfig = config;
- mZenModeHelper.updateDefaultZenRules(); // shouldn't throw null pointer
+ mZenModeHelper.updateDefaultZenRules(
+ Process.SYSTEM_UID, true); // shouldn't throw null pointer
mZenModeHelper.pullRules(events); // shouldn't throw null pointer
}
@@ -1577,7 +1590,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
autoRules.put(SCHEDULE_DEFAULT_RULE_ID, updatedDefaultRule);
mZenModeHelper.mConfig.automaticRules = autoRules;
- mZenModeHelper.updateDefaultZenRules();
+ mZenModeHelper.updateDefaultZenRules(Process.SYSTEM_UID, true);
assertEquals(updatedDefaultRule,
mZenModeHelper.mConfig.automaticRules.get(SCHEDULE_DEFAULT_RULE_ID));
}
@@ -1603,7 +1616,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
autoRules.put(SCHEDULE_DEFAULT_RULE_ID, updatedDefaultRule);
mZenModeHelper.mConfig.automaticRules = autoRules;
- mZenModeHelper.updateDefaultZenRules();
+ mZenModeHelper.updateDefaultZenRules(Process.SYSTEM_UID, true);
assertEquals(updatedDefaultRule,
mZenModeHelper.mConfig.automaticRules.get(SCHEDULE_DEFAULT_RULE_ID));
}
@@ -1630,7 +1643,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
autoRules.put(SCHEDULE_DEFAULT_RULE_ID, customDefaultRule);
mZenModeHelper.mConfig.automaticRules = autoRules;
- mZenModeHelper.updateDefaultZenRules();
+ mZenModeHelper.updateDefaultZenRules(Process.SYSTEM_UID, true);
ZenModeConfig.ZenRule ruleAfterUpdating =
mZenModeHelper.mConfig.automaticRules.get(SCHEDULE_DEFAULT_RULE_ID);
assertEquals(customDefaultRule.enabled, ruleAfterUpdating.enabled);
@@ -1653,7 +1666,8 @@ public class ZenModeHelperTest extends UiServiceTestCase {
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
// We need the package name to be something that's not "android" so there aren't any
// existing rules under that package.
- String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test");
+ String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test",
+ CUSTOM_PKG_UID, false);
assertNotNull(id);
}
try {
@@ -1663,7 +1677,8 @@ public class ZenModeHelperTest extends UiServiceTestCase {
ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
new ZenPolicy.Builder().build(),
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
- String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test");
+ String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test",
+ CUSTOM_PKG_UID, false);
fail("allowed too many rules to be created");
} catch (IllegalArgumentException e) {
// yay
@@ -1683,7 +1698,8 @@ public class ZenModeHelperTest extends UiServiceTestCase {
ZenModeConfig.toScheduleConditionId(si),
new ZenPolicy.Builder().build(),
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
- String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test");
+ String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test",
+ CUSTOM_PKG_UID, false);
assertNotNull(id);
}
try {
@@ -1693,7 +1709,8 @@ public class ZenModeHelperTest extends UiServiceTestCase {
ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
new ZenPolicy.Builder().build(),
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
- String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test");
+ String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test",
+ CUSTOM_PKG_UID, false);
fail("allowed too many rules to be created");
} catch (IllegalArgumentException e) {
// yay
@@ -1713,7 +1730,8 @@ public class ZenModeHelperTest extends UiServiceTestCase {
ZenModeConfig.toScheduleConditionId(si),
new ZenPolicy.Builder().build(),
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
- String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test");
+ String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test",
+ CUSTOM_PKG_UID, false);
assertNotNull(id);
}
try {
@@ -1723,7 +1741,8 @@ public class ZenModeHelperTest extends UiServiceTestCase {
ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
new ZenPolicy.Builder().build(),
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
- String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test");
+ String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test",
+ CUSTOM_PKG_UID, false);
fail("allowed too many rules to be created");
} catch (IllegalArgumentException e) {
// yay
@@ -1738,7 +1757,8 @@ public class ZenModeHelperTest extends UiServiceTestCase {
ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
new ZenPolicy.Builder().build(),
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
- String id = mZenModeHelper.addAutomaticZenRule("android", zenRule, "test");
+ String id = mZenModeHelper.addAutomaticZenRule("android", zenRule, "test",
+ Process.SYSTEM_UID, true);
assertTrue(id != null);
ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
@@ -1758,7 +1778,8 @@ public class ZenModeHelperTest extends UiServiceTestCase {
new ComponentName("android", "ScheduleConditionProvider"),
ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
- String id = mZenModeHelper.addAutomaticZenRule("android", zenRule, "test");
+ String id = mZenModeHelper.addAutomaticZenRule("android", zenRule, "test",
+ Process.SYSTEM_UID, true);
assertTrue(id != null);
ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
@@ -1781,9 +1802,11 @@ public class ZenModeHelperTest extends UiServiceTestCase {
new ZenPolicy.Builder().build(),
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
- String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, "test");
+ String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, "test",
+ CUSTOM_PKG_UID, false);
mZenModeHelper.setAutomaticZenRuleState(zenRule.getConditionId(),
- new Condition(zenRule.getConditionId(), "", STATE_TRUE));
+ new Condition(zenRule.getConditionId(), "", STATE_TRUE),
+ CUSTOM_PKG_UID, false);
ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
assertEquals(STATE_TRUE, ruleInConfig.condition.state);
@@ -1798,7 +1821,8 @@ public class ZenModeHelperTest extends UiServiceTestCase {
new ZenPolicy.Builder().build(),
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
- String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, "test");
+ String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, "test",
+ CUSTOM_PKG_UID, false);
AutomaticZenRule zenRule2 = new AutomaticZenRule("NEW",
null,
@@ -1807,7 +1831,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
new ZenPolicy.Builder().build(),
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
- mZenModeHelper.updateAutomaticZenRule(id, zenRule2, "");
+ mZenModeHelper.updateAutomaticZenRule(id, zenRule2, "", CUSTOM_PKG_UID, false);
ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
assertEquals("NEW", ruleInConfig.name);
@@ -1822,14 +1846,15 @@ public class ZenModeHelperTest extends UiServiceTestCase {
new ZenPolicy.Builder().build(),
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
- String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, "test");
+ String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, "test",
+ CUSTOM_PKG_UID, false);
assertTrue(id != null);
ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
assertTrue(ruleInConfig != null);
assertEquals(zenRule.getName(), ruleInConfig.name);
- mZenModeHelper.removeAutomaticZenRule(id, "test");
+ mZenModeHelper.removeAutomaticZenRule(id, "test", CUSTOM_PKG_UID, false);
assertNull(mZenModeHelper.mConfig.automaticRules.get(id));
}
@@ -1841,14 +1866,16 @@ public class ZenModeHelperTest extends UiServiceTestCase {
ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
new ZenPolicy.Builder().build(),
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
- String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, "test");
+ String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, "test",
+ CUSTOM_PKG_UID, false);
assertTrue(id != null);
ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
assertTrue(ruleInConfig != null);
assertEquals(zenRule.getName(), ruleInConfig.name);
- mZenModeHelper.removeAutomaticZenRules(mContext.getPackageName(), "test");
+ mZenModeHelper.removeAutomaticZenRules(mContext.getPackageName(), "test",
+ CUSTOM_PKG_UID, false);
assertNull(mZenModeHelper.mConfig.automaticRules.get(id));
}
@@ -1863,15 +1890,17 @@ public class ZenModeHelperTest extends UiServiceTestCase {
new ComponentName("android", "ScheduleConditionProvider"),
sharedUri,
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
- String id = mZenModeHelper.addAutomaticZenRule("android", zenRule, "test");
+ String id = mZenModeHelper.addAutomaticZenRule("android", zenRule, "test",
+ Process.SYSTEM_UID, true);
AutomaticZenRule zenRule2 = new AutomaticZenRule("name2",
new ComponentName("android", "ScheduleConditionProvider"),
sharedUri,
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
- String id2 = mZenModeHelper.addAutomaticZenRule("android", zenRule2, "test");
+ String id2 = mZenModeHelper.addAutomaticZenRule("android", zenRule2, "test",
+ Process.SYSTEM_UID, true);
Condition condition = new Condition(sharedUri, "", STATE_TRUE);
- mZenModeHelper.setAutomaticZenRuleState(sharedUri, condition);
+ mZenModeHelper.setAutomaticZenRuleState(sharedUri, condition, Process.SYSTEM_UID, true);
for (ZenModeConfig.ZenRule rule : mZenModeHelper.mConfig.automaticRules.values()) {
if (rule.id.equals(id)) {
@@ -1884,17 +1913,17 @@ public class ZenModeHelperTest extends UiServiceTestCase {
}
}
- condition = new Condition(sharedUri, "", Condition.STATE_FALSE);
- mZenModeHelper.setAutomaticZenRuleState(sharedUri, condition);
+ condition = new Condition(sharedUri, "", STATE_FALSE);
+ mZenModeHelper.setAutomaticZenRuleState(sharedUri, condition, Process.SYSTEM_UID, true);
for (ZenModeConfig.ZenRule rule : mZenModeHelper.mConfig.automaticRules.values()) {
if (rule.id.equals(id)) {
assertNotNull(rule.condition);
- assertTrue(rule.condition.state == Condition.STATE_FALSE);
+ assertTrue(rule.condition.state == STATE_FALSE);
}
if (rule.id.equals(id2)) {
assertNotNull(rule.condition);
- assertTrue(rule.condition.state == Condition.STATE_FALSE);
+ assertTrue(rule.condition.state == STATE_FALSE);
}
}
}
@@ -1904,14 +1933,510 @@ public class ZenModeHelperTest extends UiServiceTestCase {
setupZenConfig();
// note that caller=null because that's how it comes in from NMS.setZenMode
- mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, null, "");
+ mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, null, "",
+ Process.SYSTEM_UID, true);
// confirm that setting zen mode via setManualZenMode changed the zen mode correctly
assertEquals(ZEN_MODE_IMPORTANT_INTERRUPTIONS, mZenModeHelper.mZenMode);
// and also that it works to turn it back off again
- mZenModeHelper.setManualZenMode(Global.ZEN_MODE_OFF, null, null, "");
+ mZenModeHelper.setManualZenMode(Global.ZEN_MODE_OFF, null, null, "",
+ Process.SYSTEM_UID, true);
+
+ assertEquals(Global.ZEN_MODE_OFF, mZenModeHelper.mZenMode);
+ }
+
+ @Test
+ public void testZenModeEventLog_setManualZenMode() throws IllegalArgumentException {
+ mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
+ setupZenConfig();
+
+ // Turn zen mode on (to important_interruptions)
+ // Need to additionally call the looper in order to finish the post-apply-config process
+ mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, null, "",
+ Process.SYSTEM_UID, true);
+
+ // Now turn zen mode off, but via a different package UID -- this should get registered as
+ // "not an action by the user" because some other app is changing zen mode
+ mZenModeHelper.setManualZenMode(Global.ZEN_MODE_OFF, null, null, "", CUSTOM_PKG_UID,
+ false);
+
+ // In total, this should be 2 loggable changes
+ assertEquals(2, mZenModeEventLogger.numLoggedChanges());
+
+ // we expect the following changes from turning zen mode on:
+ // - manual rule added
+ // - zen mode -> ZEN_MODE_IMPORTANT_INTERRUPTIONS
+ // This should combine to 1 log event (zen mode turns on) with the following properties:
+ // - event ID: DND_TURNED_ON
+ // - new zen mode = important interruptions; prev zen mode = off
+ // - changed rule type = manual
+ // - rules active = 1
+ // - user action = true (system-based turning zen mode on)
+ // - package uid = system (as set above)
+ // - resulting DNDPolicyProto the same as the values in setupZenConfig()
+ assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_ON.getId(),
+ mZenModeEventLogger.getEventId(0));
+ assertEquals(Global.ZEN_MODE_OFF, mZenModeEventLogger.getPrevZenMode(0));
+ assertEquals(ZEN_MODE_IMPORTANT_INTERRUPTIONS, mZenModeEventLogger.getNewZenMode(0));
+ assertEquals(DNDProtoEnums.MANUAL_RULE, mZenModeEventLogger.getChangedRuleType(0));
+ assertEquals(1, mZenModeEventLogger.getNumRulesActive(0));
+ assertTrue(mZenModeEventLogger.getFromSystemOrSystemUi(0));
+ assertTrue(mZenModeEventLogger.getIsUserAction(0));
+ assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(0));
+ checkDndProtoMatchesSetupZenConfig(mZenModeEventLogger.getPolicyProto(0));
+
+ // and from turning zen mode off:
+ // - event ID: DND_TURNED_OFF
+ // - new zen mode = off; previous = important interruptions
+ // - changed rule type = manual
+ // - rules active = 0
+ // - user action = false
+ // - package uid = custom one passed in above
+ // - DNDPolicyProto still the same
+ assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_OFF.getId(),
+ mZenModeEventLogger.getEventId(1));
+ assertEquals(ZEN_MODE_IMPORTANT_INTERRUPTIONS, mZenModeEventLogger.getPrevZenMode(1));
+ assertEquals(Global.ZEN_MODE_OFF, mZenModeEventLogger.getNewZenMode(1));
+ assertEquals(DNDProtoEnums.MANUAL_RULE, mZenModeEventLogger.getChangedRuleType(1));
+ assertEquals(0, mZenModeEventLogger.getNumRulesActive(1));
+ assertFalse(mZenModeEventLogger.getIsUserAction(1));
+ assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(1));
+ checkDndProtoMatchesSetupZenConfig(mZenModeEventLogger.getPolicyProto(1));
+ }
+
+ @Test
+ public void testZenModeEventLog_automaticRules() throws IllegalArgumentException {
+ mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
+ setupZenConfig();
+
+ // Add a new automatic zen rule that's enabled
+ AutomaticZenRule zenRule = new AutomaticZenRule("name",
+ null,
+ new ComponentName(CUSTOM_PKG_NAME, "ScheduleConditionProvider"),
+ ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
+ null,
+ NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
+ String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule,
+ "test", Process.SYSTEM_UID, true);
+
+ // Event 1: Mimic the rule coming on automatically by setting the Condition to STATE_TRUE
+ mZenModeHelper.setAutomaticZenRuleState(id,
+ new Condition(zenRule.getConditionId(), "", STATE_TRUE),
+ Process.SYSTEM_UID, true);
+
+ // Event 2: "User" turns off the automatic rule (sets it to not enabled)
+ zenRule.setEnabled(false);
+ mZenModeHelper.updateAutomaticZenRule(id, zenRule, "", Process.SYSTEM_UID, true);
+
+ // Add a new system rule
+ AutomaticZenRule systemRule = new AutomaticZenRule("systemRule",
+ null,
+ new ComponentName("android", "ScheduleConditionProvider"),
+ ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
+ null,
+ NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
+ String systemId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), systemRule,
+ "test", Process.SYSTEM_UID, true);
+
+ // Event 3: turn on the system rule
+ mZenModeHelper.setAutomaticZenRuleState(systemId,
+ new Condition(zenRule.getConditionId(), "", STATE_TRUE),
+ Process.SYSTEM_UID, true);
+
+ // Event 4: "User" deletes the rule
+ mZenModeHelper.removeAutomaticZenRule(systemId, "", Process.SYSTEM_UID, true);
+
+ // In total, this represents 4 events
+ assertEquals(4, mZenModeEventLogger.numLoggedChanges());
+
+ // We should see an event from the automatic rule turning on; it should have the following
+ // properties:
+ // - event ID: DND_TURNED_ON
+ // - zen mode: OFF -> IMPORTANT_INTERRUPTIONS
+ // - automatic rule change
+ // - 1 rule (newly) active
+ // - automatic (is not a user action)
+ // - package UID is written to be the rule *owner* even though it "comes from system"
+ // - zen policy is the same as the set-up zen config
+ assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_ON.getId(),
+ mZenModeEventLogger.getEventId(0));
+ assertEquals(Global.ZEN_MODE_OFF, mZenModeEventLogger.getPrevZenMode(0));
+ assertEquals(ZEN_MODE_IMPORTANT_INTERRUPTIONS, mZenModeEventLogger.getNewZenMode(0));
+ assertEquals(DNDProtoEnums.AUTOMATIC_RULE, mZenModeEventLogger.getChangedRuleType(0));
+ assertEquals(1, mZenModeEventLogger.getNumRulesActive(0));
+ assertFalse(mZenModeEventLogger.getIsUserAction(0));
+ assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(0));
+ checkDndProtoMatchesSetupZenConfig(mZenModeEventLogger.getPolicyProto(0));
+
+ // When the automatic rule is disabled, this should turn off zen mode and also count as a
+ // user action.
+ assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_OFF.getId(),
+ mZenModeEventLogger.getEventId(1));
+ assertEquals(ZEN_MODE_IMPORTANT_INTERRUPTIONS, mZenModeEventLogger.getPrevZenMode(1));
+ assertEquals(Global.ZEN_MODE_OFF, mZenModeEventLogger.getNewZenMode(1));
+ assertEquals(DNDProtoEnums.AUTOMATIC_RULE, mZenModeEventLogger.getChangedRuleType(1));
+ assertEquals(0, mZenModeEventLogger.getNumRulesActive(1));
+ assertTrue(mZenModeEventLogger.getIsUserAction(1));
+ assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(1));
+ checkDndProtoMatchesSetupZenConfig(mZenModeEventLogger.getPolicyProto(1));
+
+ // When the system rule is enabled, this counts as an automatic action that comes from the
+ // system and turns on DND
+ assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_ON.getId(),
+ mZenModeEventLogger.getEventId(2));
+ assertEquals(DNDProtoEnums.AUTOMATIC_RULE, mZenModeEventLogger.getChangedRuleType(2));
+ assertEquals(1, mZenModeEventLogger.getNumRulesActive(2));
+ assertFalse(mZenModeEventLogger.getIsUserAction(2));
+ assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(2));
+
+ // When the system rule is deleted, we consider this a user action that turns DND off
+ // (again)
+ assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_OFF.getId(),
+ mZenModeEventLogger.getEventId(3));
+ assertEquals(DNDProtoEnums.AUTOMATIC_RULE, mZenModeEventLogger.getChangedRuleType(3));
+ assertEquals(0, mZenModeEventLogger.getNumRulesActive(3));
+ assertTrue(mZenModeEventLogger.getIsUserAction(3));
+ assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(3));
+ }
+
+ @Test
+ public void testZenModeEventLog_policyChanges() throws IllegalArgumentException {
+ mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
+ setupZenConfig();
+
+ // First just turn zen mode on
+ mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, null, "",
+ Process.SYSTEM_UID, true);
+
+ // Now change the policy slightly; want to confirm that this'll be reflected in the logs
+ ZenModeConfig newConfig = mZenModeHelper.mConfig.copy();
+ newConfig.allowAlarms = true;
+ newConfig.allowRepeatCallers = false;
+ mZenModeHelper.setNotificationPolicy(newConfig.toNotificationPolicy(), Process.SYSTEM_UID,
+ true);
+
+ // Turn zen mode off; we want to make sure policy changes do not get logged when zen mode
+ // is off.
+ mZenModeHelper.setManualZenMode(Global.ZEN_MODE_OFF, null, null, "",
+ Process.SYSTEM_UID, true);
+
+ // Change the policy again
+ newConfig.allowMessages = false;
+ newConfig.allowRepeatCallers = true;
+ mZenModeHelper.setNotificationPolicy(newConfig.toNotificationPolicy(), Process.SYSTEM_UID,
+ true);
+
+ // Total events: we only expect ones for turning on, changing policy, and turning off
+ assertEquals(3, mZenModeEventLogger.numLoggedChanges());
+
+ // The first event is just turning DND on; make sure the policy is what we expect there
+ // before it changes in the next stage
+ assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_ON.getId(),
+ mZenModeEventLogger.getEventId(0));
+ checkDndProtoMatchesSetupZenConfig(mZenModeEventLogger.getPolicyProto(0));
+
+ // Second message where we change the policy:
+ // - DND_POLICY_CHANGED (indicates only the policy changed and nothing else)
+ // - rule type: unknown (it's a policy change, not a rule change)
+ // - user action (because it comes from a "system" uid)
+ // - check the specific things changed above
+ assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_POLICY_CHANGED.getId(),
+ mZenModeEventLogger.getEventId(1));
+ assertEquals(DNDProtoEnums.UNKNOWN_RULE, mZenModeEventLogger.getChangedRuleType(1));
+ assertTrue(mZenModeEventLogger.getIsUserAction(1));
+ assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(1));
+ DNDPolicyProto dndProto = mZenModeEventLogger.getPolicyProto(1);
+ assertEquals(STATE_ALLOW, dndProto.getAlarms().getNumber());
+ assertEquals(STATE_DISALLOW, dndProto.getRepeatCallers().getNumber());
+
+ // The third and final event should turn DND off
+ assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_OFF.getId(),
+ mZenModeEventLogger.getEventId(2));
+
+ // There should be no fourth event for changing the policy the second time.
+ }
+
+ @Test
+ public void testZenModeEventLog_ruleCounts() throws IllegalArgumentException {
+ mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
+ setupZenConfig();
+
+ AutomaticZenRule zenRule = new AutomaticZenRule("name",
+ null,
+ new ComponentName(CUSTOM_PKG_NAME, "ScheduleConditionProvider"),
+ ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
+ null,
+ NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
+ String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule, "test",
+ Process.SYSTEM_UID, true);
+
+ // Rule 2, same as rule 1
+ AutomaticZenRule zenRule2 = new AutomaticZenRule("name2",
+ null,
+ new ComponentName(CUSTOM_PKG_NAME, "ScheduleConditionProvider"),
+ ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
+ null,
+ NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
+ String id2 = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule2, "test",
+ Process.SYSTEM_UID, true);
+
+ // Rule 3, has stricter settings than the default settings
+ ZenModeConfig ruleConfig = mZenModeHelper.mConfig.copy();
+ ruleConfig.allowReminders = false;
+ ruleConfig.allowCalls = false;
+ ruleConfig.allowMessages = false;
+ AutomaticZenRule zenRule3 = new AutomaticZenRule("name3",
+ null,
+ new ComponentName("android", "ScheduleConditionProvider"),
+ ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
+ ruleConfig.toZenPolicy(),
+ NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
+ String id3 = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule3, "test",
+ Process.SYSTEM_UID, true);
+
+ // First: turn on rule 1
+ mZenModeHelper.setAutomaticZenRuleState(id,
+ new Condition(zenRule.getConditionId(), "", STATE_TRUE),
+ Process.SYSTEM_UID, true);
+
+ // Second: turn on rule 2
+ mZenModeHelper.setAutomaticZenRuleState(id2,
+ new Condition(zenRule2.getConditionId(), "", STATE_TRUE),
+ Process.SYSTEM_UID, true);
+
+ // Third: turn on rule 3
+ mZenModeHelper.setAutomaticZenRuleState(id3,
+ new Condition(zenRule3.getConditionId(), "", STATE_TRUE),
+ Process.SYSTEM_UID, true);
+
+ // Fourth: Turn *off* rule 2
+ mZenModeHelper.setAutomaticZenRuleState(id2,
+ new Condition(zenRule2.getConditionId(), "", STATE_FALSE),
+ Process.SYSTEM_UID, true);
+
+ // This should result in a total of four events
+ assertEquals(4, mZenModeEventLogger.numLoggedChanges());
+
+ // Event 1: rule 1 turns on. We expect this to turn on DND (zen mode) overall, so that's
+ // what the event should reflect. At this time, the policy is the same as initial setup.
+ assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_ON.getId(),
+ mZenModeEventLogger.getEventId(0));
+ assertEquals(Global.ZEN_MODE_OFF, mZenModeEventLogger.getPrevZenMode(0));
+ assertEquals(ZEN_MODE_IMPORTANT_INTERRUPTIONS, mZenModeEventLogger.getNewZenMode(0));
+ assertEquals(1, mZenModeEventLogger.getNumRulesActive(0));
+ assertFalse(mZenModeEventLogger.getIsUserAction(0));
+ assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(0));
+ checkDndProtoMatchesSetupZenConfig(mZenModeEventLogger.getPolicyProto(0));
+
+ // Event 2: rule 2 turns on. This should not change anything about the policy, so the only
+ // change is that there are more rules active now.
+ assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_ACTIVE_RULES_CHANGED.getId(),
+ mZenModeEventLogger.getEventId(1));
+ assertEquals(2, mZenModeEventLogger.getNumRulesActive(1));
+ assertFalse(mZenModeEventLogger.getIsUserAction(1));
+ assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(1));
+ checkDndProtoMatchesSetupZenConfig(mZenModeEventLogger.getPolicyProto(1));
+
+ // Event 3: rule 3 turns on. This should trigger a policy change, and be classified as such,
+ // but meanwhile also change the number of active rules.
+ // Rule 3 is also set up to be a "system"-owned rule, so the caller UID should remain system
+ assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_POLICY_CHANGED.getId(),
+ mZenModeEventLogger.getEventId(2));
+ assertEquals(3, mZenModeEventLogger.getNumRulesActive(2));
+ assertFalse(mZenModeEventLogger.getIsUserAction(2));
+ assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(2));
+ DNDPolicyProto dndProto = mZenModeEventLogger.getPolicyProto(2);
+ assertEquals(STATE_DISALLOW, dndProto.getReminders().getNumber());
+ assertEquals(STATE_DISALLOW, dndProto.getCalls().getNumber());
+ assertEquals(STATE_DISALLOW, dndProto.getMessages().getNumber());
+
+ // Event 4: rule 2 turns off. Because rule 3 is still on and stricter than rule 1 (also
+ // still on), there should be no policy change as a result of rule 2 going away. Therefore
+ // this event should again only be an active rule change.
+ assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_ACTIVE_RULES_CHANGED.getId(),
+ mZenModeEventLogger.getEventId(3));
+ assertEquals(2, mZenModeEventLogger.getNumRulesActive(3));
+ assertFalse(mZenModeEventLogger.getIsUserAction(3));
+ }
+
+ @Test
+ public void testZenModeEventLog_noLogWithNoConfigChange() throws IllegalArgumentException {
+ // If evaluateZenMode is called independently of a config change, don't log.
+ mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
+ setupZenConfig();
+
+ // Artificially turn zen mode "on". Re-evaluating zen mode should cause it to turn back off
+ // given that we don't have any zen rules active.
+ mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ mZenModeHelper.evaluateZenMode("test", true);
+
+ // Check that the change actually took: zen mode should be off now
assertEquals(Global.ZEN_MODE_OFF, mZenModeHelper.mZenMode);
+
+ // but still, nothing should've been logged
+ assertEquals(0, mZenModeEventLogger.numLoggedChanges());
+ }
+
+ @Test
+ public void testZenModeEventLog_reassignUid() throws IllegalArgumentException {
+ // Test that, only in specific cases, we reassign the calling UID to one associated with
+ // the automatic rule owner.
+ mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
+ setupZenConfig();
+
+ // Rule 1, owned by a package
+ AutomaticZenRule zenRule = new AutomaticZenRule("name",
+ null,
+ new ComponentName(CUSTOM_PKG_NAME, "ScheduleConditionProvider"),
+ ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
+ null,
+ NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
+ String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule, "test",
+ Process.SYSTEM_UID, true);
+
+ // Rule 2, same as rule 1 but owned by the system
+ AutomaticZenRule zenRule2 = new AutomaticZenRule("name2",
+ null,
+ new ComponentName("android", "ScheduleConditionProvider"),
+ ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
+ null,
+ NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
+ String id2 = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule2, "test",
+ Process.SYSTEM_UID, true);
+
+ // Turn on rule 1; call looks like it's from the system. Because setting a condition is
+ // typically an automatic (non-user-initiated) action, expect the calling UID to be
+ // re-evaluated to the one associat.d with CUSTOM_PKG_NAME.
+ mZenModeHelper.setAutomaticZenRuleState(id,
+ new Condition(zenRule.getConditionId(), "", STATE_TRUE),
+ Process.SYSTEM_UID, true);
+
+ // Second: turn on rule 2. This is a system-owned rule and the UID should not be modified
+ // (nor even looked up; the mock PackageManager won't handle "android" as input).
+ mZenModeHelper.setAutomaticZenRuleState(id2,
+ new Condition(zenRule2.getConditionId(), "", STATE_TRUE),
+ Process.SYSTEM_UID, true);
+
+ // Disable rule 1. Because this looks like a user action, the UID should not be modified
+ // from the system-provided one.
+ zenRule.setEnabled(false);
+ mZenModeHelper.updateAutomaticZenRule(id, zenRule, "", Process.SYSTEM_UID, true);
+
+ // Add a manual rule. Any manual rule changes should not get calling uids reassigned.
+ mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, null, "",
+ CUSTOM_PKG_UID, false);
+
+ // Change rule 2's condition, but from some other UID. Since it doesn't look like it's from
+ // the system, we keep the UID info.
+ mZenModeHelper.setAutomaticZenRuleState(id2,
+ new Condition(zenRule2.getConditionId(), "", STATE_FALSE),
+ 12345, false);
+
+ // That was 5 events total
+ assertEquals(5, mZenModeEventLogger.numLoggedChanges());
+
+ // The first event (activating rule 1) should be of type "zen mode turns on", automatic,
+ // have a package UID of CUSTOM_PKG_UID
+ assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_ON.getId(),
+ mZenModeEventLogger.getEventId(0));
+ assertEquals(DNDProtoEnums.AUTOMATIC_RULE, mZenModeEventLogger.getChangedRuleType(0));
+ assertFalse(mZenModeEventLogger.getIsUserAction(0));
+ assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(0));
+
+ // The second event (activating rule 2) should have similar other properties but the UID
+ // should be system.
+ assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_ACTIVE_RULES_CHANGED.getId(),
+ mZenModeEventLogger.getEventId(1));
+ assertEquals(DNDProtoEnums.AUTOMATIC_RULE, mZenModeEventLogger.getChangedRuleType(1));
+ assertFalse(mZenModeEventLogger.getIsUserAction(1));
+ assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(1));
+
+ // Third event: disable rule 1. This looks like a user action so UID should be left alone.
+ assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_ACTIVE_RULES_CHANGED.getId(),
+ mZenModeEventLogger.getEventId(2));
+ assertEquals(DNDProtoEnums.AUTOMATIC_RULE, mZenModeEventLogger.getChangedRuleType(2));
+ assertTrue(mZenModeEventLogger.getIsUserAction(2));
+ assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(2));
+
+ // Fourth event: turns on manual mode. Doesn't change effective policy so this is just a
+ // change in active rules. Confirm that the package UID is left unchanged.
+ // Because it's a manual mode change not from the system, isn't considered a user action.
+ assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_ACTIVE_RULES_CHANGED.getId(),
+ mZenModeEventLogger.getEventId(3));
+ assertEquals(DNDProtoEnums.MANUAL_RULE, mZenModeEventLogger.getChangedRuleType(3));
+ assertFalse(mZenModeEventLogger.getIsUserAction(3));
+ assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(3));
+
+ // Fourth event: changed condition on rule 2 (turning it off via condition).
+ // This comes from a random different UID so we expect that to remain untouched.
+ assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_ACTIVE_RULES_CHANGED.getId(),
+ mZenModeEventLogger.getEventId(4));
+ assertEquals(DNDProtoEnums.AUTOMATIC_RULE, mZenModeEventLogger.getChangedRuleType(4));
+ assertFalse(mZenModeEventLogger.getIsUserAction(4));
+ assertEquals(12345, mZenModeEventLogger.getPackageUid(4));
+ }
+
+ @Test
+ public void testZenModeEventLog_channelsBypassingChanges() {
+ // Verify that the right thing happens when the canBypassDnd value changes.
+ mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
+ setupZenConfig();
+
+ // Turn on zen mode with a manual rule with an enabler set. This should *not* count
+ // as a user action, and *should* get its UID reassigned.
+ mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null,
+ CUSTOM_PKG_NAME, "", Process.SYSTEM_UID, true);
+
+ // Now change apps bypassing to true
+ ZenModeConfig newConfig = mZenModeHelper.mConfig.copy();
+ newConfig.areChannelsBypassingDnd = true;
+ mZenModeHelper.setNotificationPolicy(newConfig.toNotificationPolicy(), Process.SYSTEM_UID,
+ true);
+
+ // and then back to false, all without changing anything else
+ newConfig.areChannelsBypassingDnd = false;
+ mZenModeHelper.setNotificationPolicy(newConfig.toNotificationPolicy(), Process.SYSTEM_UID,
+ true);
+
+ // Turn off manual mode, call from a package: don't reset UID even though enabler is set
+ mZenModeHelper.setManualZenMode(Global.ZEN_MODE_OFF, null,
+ CUSTOM_PKG_NAME, "", 12345, false);
+
+ // And likewise when turning it back on again
+ mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null,
+ CUSTOM_PKG_NAME, "", 12345, false);
+
+ // These are 5 events in total.
+ assertEquals(5, mZenModeEventLogger.numLoggedChanges());
+
+ // First event: turns on, UID reassigned for manual mode
+ assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_ON.getId(),
+ mZenModeEventLogger.getEventId(0));
+ assertFalse(mZenModeEventLogger.getIsUserAction(0));
+ assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(0));
+
+ // Second event should be a policy-only change with are channels bypassing = true
+ assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_POLICY_CHANGED.getId(),
+ mZenModeEventLogger.getEventId(1));
+ assertTrue(mZenModeEventLogger.getAreChannelsBypassing(1));
+
+ // Third event also a policy-only change but with channels bypassing now false
+ assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_POLICY_CHANGED.getId(),
+ mZenModeEventLogger.getEventId(2));
+ assertFalse(mZenModeEventLogger.getAreChannelsBypassing(2));
+
+ // Fourth event: should turn DND off, not have UID reassigned
+ assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_OFF.getId(),
+ mZenModeEventLogger.getEventId(3));
+ assertFalse(mZenModeEventLogger.getIsUserAction(3));
+ assertEquals(12345, mZenModeEventLogger.getPackageUid(3));
+
+ // Fifth event: turn DND back on, not have UID reassigned
+ assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_ON.getId(),
+ mZenModeEventLogger.getEventId(4));
+ assertFalse(mZenModeEventLogger.getIsUserAction(4));
+ assertEquals(12345, mZenModeEventLogger.getPackageUid(4));
}
private void setupZenConfig() {
@@ -1921,7 +2446,9 @@ public class ZenModeHelperTest extends UiServiceTestCase {
mZenModeHelper.mConfig.allowSystem = false;
mZenModeHelper.mConfig.allowReminders = true;
mZenModeHelper.mConfig.allowCalls = true;
+ mZenModeHelper.mConfig.allowCallsFrom = PRIORITY_SENDERS_STARRED;
mZenModeHelper.mConfig.allowMessages = true;
+ mZenModeHelper.mConfig.allowConversations = true;
mZenModeHelper.mConfig.allowEvents = true;
mZenModeHelper.mConfig.allowRepeatCallers = true;
mZenModeHelper.mConfig.suppressedVisualEffects = SUPPRESSED_EFFECT_BADGE;
@@ -1935,12 +2462,33 @@ public class ZenModeHelperTest extends UiServiceTestCase {
assertFalse(mZenModeHelper.mConfig.allowSystem);
assertTrue(mZenModeHelper.mConfig.allowReminders);
assertTrue(mZenModeHelper.mConfig.allowCalls);
+ assertEquals(PRIORITY_SENDERS_STARRED, mZenModeHelper.mConfig.allowCallsFrom);
assertTrue(mZenModeHelper.mConfig.allowMessages);
+ assertTrue(mZenModeHelper.mConfig.allowConversations);
assertTrue(mZenModeHelper.mConfig.allowEvents);
assertTrue(mZenModeHelper.mConfig.allowRepeatCallers);
assertEquals(SUPPRESSED_EFFECT_BADGE, mZenModeHelper.mConfig.suppressedVisualEffects);
}
+ private void checkDndProtoMatchesSetupZenConfig(DNDPolicyProto dndProto) {
+ assertEquals(STATE_DISALLOW, dndProto.getAlarms().getNumber());
+ assertEquals(STATE_DISALLOW, dndProto.getMedia().getNumber());
+ assertEquals(STATE_DISALLOW, dndProto.getSystem().getNumber());
+ assertEquals(STATE_ALLOW, dndProto.getReminders().getNumber());
+ assertEquals(STATE_ALLOW, dndProto.getCalls().getNumber());
+ assertEquals(PEOPLE_STARRED, dndProto.getAllowCallsFrom().getNumber());
+ assertEquals(STATE_ALLOW, dndProto.getMessages().getNumber());
+ assertEquals(STATE_ALLOW, dndProto.getEvents().getNumber());
+ assertEquals(STATE_ALLOW, dndProto.getRepeatCallers().getNumber());
+ assertEquals(STATE_ALLOW, dndProto.getFullscreen().getNumber());
+ assertEquals(STATE_ALLOW, dndProto.getLights().getNumber());
+ assertEquals(STATE_ALLOW, dndProto.getPeek().getNumber());
+ assertEquals(STATE_ALLOW, dndProto.getStatusBar().getNumber());
+ assertEquals(STATE_DISALLOW, dndProto.getBadge().getNumber());
+ assertEquals(STATE_ALLOW, dndProto.getAmbient().getNumber());
+ assertEquals(STATE_ALLOW, dndProto.getNotificationList().getNumber());
+ }
+
/**
* Wrapper to use TypedXmlPullParser as XmlResourceParser for Resources.getXml()
*/