summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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()
*/