diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index 052358bb83975..414b53d209e84 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -566,6 +566,7 @@ message Atom { DataUsageBytesTransfer data_usage_bytes_transfer = 10082 [(module) = "framework"]; BytesTransferByTagAndMetered bytes_transfer_by_tag_and_metered = 10083 [(module) = "framework"]; + DNDModeProto dnd_mode_rule = 10084 [(module) = "framework"]; } // DO NOT USE field numbers above 100,000 in AOSP. @@ -6082,6 +6083,76 @@ message PackageNotificationChannelPreferences { optional bool is_important_conversation = 10; } +/** + * Atom that represents an item in the list of Do Not Disturb rules, pulled from + * NotificationManagerService.java. + */ +message DNDModeProto { + enum Mode { + ROOT_CONFIG = -1; // Used to distinguish the config (one per user) from the rules. + ZEN_MODE_OFF = 0; + ZEN_MODE_IMPORTANT_INTERRUPTIONS = 1; + ZEN_MODE_NO_INTERRUPTIONS = 2; + ZEN_MODE_ALARMS = 3; + } + optional int32 user = 1; // Android user ID (0, 1, 10, ...) + optional bool enabled = 2; // true for ROOT_CONFIG if a manualRule is enabled + optional bool channels_bypassing = 3; // only valid for ROOT_CONFIG + optional Mode zen_mode = 4; + // id is one of the system default rule IDs, or empty + // May also be "MANUAL_RULE" to indicate app-activation of the manual rule. + optional string id = 5; + optional int32 uid = 6 [(is_uid) = true]; // currently only SYSTEM_UID or 0 for other + optional DNDPolicyProto policy = 7; +} + +/** + * Atom that represents a Do Not Disturb policy, an optional detail proto for DNDModeProto. + */ +message DNDPolicyProto { + enum State { + STATE_UNSET = 0; + STATE_ALLOW = 1; + STATE_DISALLOW = 2; + } + optional State calls = 1; + optional State repeat_callers = 2; + optional State messages = 3; + optional State conversations = 4; + optional State reminders = 5; + optional State events = 6; + optional State alarms = 7; + optional State media = 8; + optional State system = 9; + optional State fullscreen = 10; + optional State lights = 11; + optional State peek = 12; + optional State status_bar = 13; + optional State badge = 14; + optional State ambient = 15; + optional State notification_list = 16; + + enum PeopleType { + PEOPLE_UNSET = 0; + PEOPLE_ANYONE = 1; + PEOPLE_CONTACTS = 2; + PEOPLE_STARRED = 3; + PEOPLE_NONE = 4; + } + + optional PeopleType allow_calls_from = 17; + optional PeopleType allow_messages_from = 18; + + enum ConversationType { + CONV_UNSET = 0; + CONV_ANYONE = 1; + CONV_IMPORTANT = 2; + CONV_NONE = 3; + } + + optional ConversationType allow_conversations_from = 19; +} + /** * Atom that contains a list of a package's channel group preferences, pulled from * NotificationManagerService.java. diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java index 1f6555c85a667..0827fef602522 100644 --- a/core/java/android/service/notification/ZenModeConfig.java +++ b/core/java/android/service/notification/ZenModeConfig.java @@ -78,6 +78,7 @@ public class ZenModeConfig implements Parcelable { private static final int DEFAULT_SOURCE = SOURCE_CONTACT; private static final int DEFAULT_CALLS_SOURCE = SOURCE_STAR; + public static final String MANUAL_RULE_ID = "MANUAL_RULE"; public static final String EVENTS_DEFAULT_RULE_ID = "EVENTS_DEFAULT_RULE"; public static final String EVERY_NIGHT_DEFAULT_RULE_ID = "EVERY_NIGHT_DEFAULT_RULE"; public static final List DEFAULT_RULE_IDS = Arrays.asList(EVERY_NIGHT_DEFAULT_RULE_ID, @@ -958,6 +959,48 @@ public class ZenModeConfig implements Parcelable { } }; + /** + * Converts a ZenModeConfig to a ZenPolicy + */ + public ZenPolicy toZenPolicy() { + ZenPolicy.Builder builder = new ZenPolicy.Builder() + .allowCalls(allowCalls + ? ZenModeConfig.getZenPolicySenders(allowCallsFrom) + : ZenPolicy.PEOPLE_TYPE_NONE) + .allowRepeatCallers(allowRepeatCallers) + .allowMessages(allowMessages + ? ZenModeConfig.getZenPolicySenders(allowMessagesFrom) + : ZenPolicy.PEOPLE_TYPE_NONE) + .allowReminders(allowReminders) + .allowEvents(allowEvents) + .allowAlarms(allowAlarms) + .allowMedia(allowMedia) + .allowSystem(allowSystem) + .allowConversations(allowConversations + ? ZenModeConfig.getZenPolicySenders(allowConversationsFrom) + : ZenPolicy.PEOPLE_TYPE_NONE); + if (suppressedVisualEffects == 0) { + builder.showAllVisualEffects(); + } else { + // configs don't have an unset state: wither true or false. + builder.showFullScreenIntent( + (suppressedVisualEffects & Policy.SUPPRESSED_EFFECT_FULL_SCREEN_INTENT) == 0); + builder.showLights( + (suppressedVisualEffects & SUPPRESSED_EFFECT_LIGHTS) == 0); + builder.showPeeking( + (suppressedVisualEffects & SUPPRESSED_EFFECT_PEEK) == 0); + builder.showStatusBarIcons( + (suppressedVisualEffects & Policy.SUPPRESSED_EFFECT_STATUS_BAR) == 0); + builder.showBadges( + (suppressedVisualEffects & Policy.SUPPRESSED_EFFECT_BADGE) == 0); + builder.showInAmbientDisplay( + (suppressedVisualEffects & Policy.SUPPRESSED_EFFECT_AMBIENT) == 0); + builder.showInNotificationList( + (suppressedVisualEffects & Policy.SUPPRESSED_EFFECT_NOTIFICATION_LIST) == 0); + } + return builder.build(); + } + /** * Converts a zenPolicy to a notificationPolicy using this ZenModeConfig's values as its * defaults for all unset values in zenPolicy diff --git a/core/java/android/service/notification/ZenPolicy.java b/core/java/android/service/notification/ZenPolicy.java index 87295e1c95b98..6d0bcffe148e5 100644 --- a/core/java/android/service/notification/ZenPolicy.java +++ b/core/java/android/service/notification/ZenPolicy.java @@ -24,6 +24,7 @@ import android.os.Parcel; import android.os.Parcelable; import android.util.proto.ProtoOutputStream; +import java.io.ByteArrayOutputStream; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; @@ -1110,6 +1111,40 @@ public final class ZenPolicy implements Parcelable { proto.end(token); } + /** + * Converts a policy to a statsd proto. + * @hides + */ + public byte[] toProto() { + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + ProtoOutputStream proto = new ProtoOutputStream(bytes); + + proto.write(DNDPolicyProto.CALLS, getPriorityCategoryCalls()); + proto.write(DNDPolicyProto.REPEAT_CALLERS, getPriorityCategoryRepeatCallers()); + proto.write(DNDPolicyProto.MESSAGES, getPriorityCategoryMessages()); + proto.write(DNDPolicyProto.CONVERSATIONS, getPriorityCategoryConversations()); + proto.write(DNDPolicyProto.REMINDERS, getPriorityCategoryReminders()); + proto.write(DNDPolicyProto.EVENTS, getPriorityCategoryEvents()); + proto.write(DNDPolicyProto.ALARMS, getPriorityCategoryAlarms()); + proto.write(DNDPolicyProto.MEDIA, getPriorityCategoryMedia()); + proto.write(DNDPolicyProto.SYSTEM, getPriorityCategorySystem()); + + proto.write(DNDPolicyProto.FULLSCREEN, getVisualEffectFullScreenIntent()); + proto.write(DNDPolicyProto.LIGHTS, getVisualEffectLights()); + proto.write(DNDPolicyProto.PEEK, getVisualEffectPeek()); + proto.write(DNDPolicyProto.STATUS_BAR, getVisualEffectStatusBar()); + proto.write(DNDPolicyProto.BADGE, getVisualEffectBadge()); + proto.write(DNDPolicyProto.AMBIENT, getVisualEffectAmbient()); + proto.write(DNDPolicyProto.NOTIFICATION_LIST, getVisualEffectNotificationList()); + + proto.write(DNDPolicyProto.ALLOW_CALLS_FROM, getPriorityCallSenders()); + proto.write(DNDPolicyProto.ALLOW_MESSAGES_FROM, getPriorityMessageSenders()); + proto.write(DNDPolicyProto.ALLOW_CONVERSATIONS_FROM, getPriorityConversationSenders()); + + proto.flush(); + return bytes.toByteArray(); + } + /** * Makes deep copy of this ZenPolicy. * @hide diff --git a/core/proto/android/service/notification.proto b/core/proto/android/service/notification.proto index ecb4193a2c6c1..8e4006aa68614 100644 --- a/core/proto/android/service/notification.proto +++ b/core/proto/android/service/notification.proto @@ -274,4 +274,74 @@ message PackageRemoteViewInfoProto { // Next Tag: 2 message NotificationRemoteViewsProto { repeated PackageRemoteViewInfoProto package_remote_view_info = 1; -} \ No newline at end of file +} + +/** + * Atom that represents an item in the list of Do Not Disturb rules, pulled from + * NotificationManagerService.java. + */ +message DNDModeProto { + enum Mode { + ROOT_CONFIG = -1; // Used to distinguish the config (one per user) from the rules. + ZEN_MODE_OFF = 0; + ZEN_MODE_IMPORTANT_INTERRUPTIONS = 1; + ZEN_MODE_NO_INTERRUPTIONS = 2; + ZEN_MODE_ALARMS = 3; + } + optional int32 user = 1; // Android user ID (0, 1, 10, ...) + optional bool enabled = 2; // true for ROOT_CONFIG if a manualRule is enabled + optional bool channels_bypassing = 3; // only valid for ROOT_CONFIG + optional Mode zen_mode = 4; + // id is one of the system default rule IDs, or empty + // May also be "MANUAL_RULE" to indicate app-activation of the manual rule. + optional string id = 5; + optional int32 uid = 6; // currently only SYSTEM_UID or 0 for other + optional DNDPolicyProto policy = 7; +} + +/** + * Atom that represents a Do Not Disturb policy, an optional detail proto for DNDModeProto. + */ +message DNDPolicyProto { + enum State { + STATE_UNSET = 0; + STATE_ALLOW = 1; + STATE_DISALLOW = 2; + } + optional State calls = 1; + optional State repeat_callers = 2; + optional State messages = 3; + optional State conversations = 4; + optional State reminders = 5; + optional State events = 6; + optional State alarms = 7; + optional State media = 8; + optional State system = 9; + optional State fullscreen = 10; + optional State lights = 11; + optional State peek = 12; + optional State status_bar = 13; + optional State badge = 14; + optional State ambient = 15; + optional State notification_list = 16; + + enum PeopleType { + PEOPLE_UNSET = 0; + PEOPLE_ANYONE = 1; + PEOPLE_CONTACTS = 2; + PEOPLE_STARRED = 3; + PEOPLE_NONE = 4; + } + + optional PeopleType allow_calls_from = 17; + optional PeopleType allow_messages_from = 18; + + enum ConversationType { + CONV_UNSET = 0; + CONV_ANYONE = 1; + CONV_IMPORTANT = 2; + CONV_NONE = 3; + } + + optional ConversationType allow_conversations_from = 19; +} diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 4394be2a0b127..a85d43a1d8d78 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -92,6 +92,7 @@ import static android.service.notification.NotificationListenerService.TRIM_FULL import static android.service.notification.NotificationListenerService.TRIM_LIGHT; import static android.view.WindowManager.LayoutParams.TYPE_TOAST; +import static com.android.internal.util.FrameworkStatsLog.DND_MODE_RULE; import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_CHANNEL_GROUP_PREFERENCES; import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES; import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_PREFERENCES; @@ -1906,7 +1907,8 @@ public class NotificationManagerService extends SystemService { mMetricsLogger = new MetricsLogger(); mRankingHandler = rankingHandler; mConditionProviders = conditionProviders; - mZenModeHelper = new ZenModeHelper(getContext(), mHandler.getLooper(), mConditionProviders); + mZenModeHelper = new ZenModeHelper(getContext(), mHandler.getLooper(), mConditionProviders, + new SysUiStatsEvent.BuilderFactory()); mZenModeHelper.addCallback(new ZenModeHelper.Callback() { @Override public void onConfigChanged() { @@ -2189,6 +2191,12 @@ public class NotificationManagerService extends SystemService { ConcurrentUtils.DIRECT_EXECUTOR, mPullAtomCallback ); + mStatsManager.setPullAtomCallback( + DND_MODE_RULE, + null, // use default PullAtomMetadata values + BackgroundThread.getExecutor(), + mPullAtomCallback + ); } private class StatsPullAtomCallbackImpl implements StatsManager.StatsPullAtomCallback { @@ -2198,6 +2206,7 @@ public class NotificationManagerService extends SystemService { case PACKAGE_NOTIFICATION_PREFERENCES: case PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES: case PACKAGE_NOTIFICATION_CHANNEL_GROUP_PREFERENCES: + case DND_MODE_RULE: return pullNotificationStates(atomTag, data); default: throw new UnsupportedOperationException("Unknown tagId=" + atomTag); @@ -2216,6 +2225,9 @@ public class NotificationManagerService extends SystemService { case PACKAGE_NOTIFICATION_CHANNEL_GROUP_PREFERENCES: mPreferencesHelper.pullPackageChannelGroupPreferencesStats(data); break; + case DND_MODE_RULE: + mZenModeHelper.pullRules(data); + break; } return StatsManager.PULL_SUCCESS; } diff --git a/services/core/java/com/android/server/notification/SysUiStatsEvent.java b/services/core/java/com/android/server/notification/SysUiStatsEvent.java index 9bc2346d4e963..90737bdeae4a0 100644 --- a/services/core/java/com/android/server/notification/SysUiStatsEvent.java +++ b/services/core/java/com/android/server/notification/SysUiStatsEvent.java @@ -58,6 +58,11 @@ public class SysUiStatsEvent { mBuilder.writeBoolean(value); return this; } + + public Builder writeByteArray(byte[] value) { + mBuilder.writeByteArray(value); + return this; + } } static class BuilderFactory { diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java index d03c23e0acfa4..5417275bc8f14 100644 --- a/services/core/java/com/android/server/notification/ZenModeHelper.java +++ b/services/core/java/com/android/server/notification/ZenModeHelper.java @@ -20,6 +20,10 @@ import static android.app.NotificationManager.AUTOMATIC_RULE_STATUS_DISABLED; import static android.app.NotificationManager.AUTOMATIC_RULE_STATUS_ENABLED; import static android.app.NotificationManager.AUTOMATIC_RULE_STATUS_REMOVED; import static android.app.NotificationManager.Policy.PRIORITY_SENDERS_ANY; +import static android.service.notification.DNDModeProto.ROOT_CONFIG; + +import static com.android.internal.util.FrameworkStatsLog.ANNOTATION_ID_IS_UID; +import static com.android.internal.util.FrameworkStatsLog.DND_MODE_RULE; import android.app.AppOpsManager; import android.app.AutomaticZenRule; @@ -67,6 +71,7 @@ import android.util.ArrayMap; import android.util.Log; import android.util.Slog; import android.util.SparseArray; +import android.util.StatsEvent; import android.util.proto.ProtoOutputStream; import com.android.internal.R; @@ -103,6 +108,7 @@ public class ZenModeHelper { private final SettingsObserver mSettingsObserver; private final AppOpsManager mAppOps; @VisibleForTesting protected final NotificationManager mNotificationManager; + private final SysUiStatsEvent.BuilderFactory mStatsEventBuilderFactory; @VisibleForTesting protected ZenModeConfig mDefaultConfig; private final ArrayList mCallbacks = new ArrayList(); private final ZenModeFiltering mFiltering; @@ -130,7 +136,8 @@ public class ZenModeHelper { private String[] mPriorityOnlyDndExemptPackages; - public ZenModeHelper(Context context, Looper looper, ConditionProviders conditionProviders) { + public ZenModeHelper(Context context, Looper looper, ConditionProviders conditionProviders, + SysUiStatsEvent.BuilderFactory statsEventBuilderFactory) { mContext = context; mHandler = new H(looper); addCallback(mMetrics); @@ -148,6 +155,7 @@ public class ZenModeHelper { mFiltering = new ZenModeFiltering(mContext); mConditions = new ZenModeConditions(this, conditionProviders); mServiceConfig = conditionProviders.getConfig(); + mStatsEventBuilderFactory = statsEventBuilderFactory; } public Looper getLooper() { @@ -1170,6 +1178,72 @@ public class ZenModeHelper { } } + /** + * Generate pulled atoms about do not disturb configurations. + */ + public void pullRules(List events) { + synchronized (mConfig) { + final int numConfigs = mConfigs.size(); + int id = 0; + for (int i = 0; i < numConfigs; i++) { + final int user = mConfigs.keyAt(i); + final ZenModeConfig config = mConfigs.valueAt(i); + SysUiStatsEvent.Builder data = mStatsEventBuilderFactory.newBuilder() + .setAtomId(DND_MODE_RULE) + .writeInt(user) + .writeBoolean(config.manualRule != null) // enabled + .writeBoolean(config.areChannelsBypassingDnd) + .writeInt(ROOT_CONFIG) + .writeString("") // name, empty for root config + .writeInt(Process.SYSTEM_UID) // system owns root config + .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true) + .writeByteArray(config.toZenPolicy().toProto()); + events.add(data.build()); + if (config.manualRule != null && config.manualRule.enabler != null) { + ruleToProto(user, config.manualRule, events); + } + for (ZenRule rule : config.automaticRules.values()) { + ruleToProto(user, rule, events); + } + } + } + } + + private void ruleToProto(int user, ZenRule rule, List events) { + // Make the ID safe. + String id = rule.id == null ? "" : rule.id; + if (!ZenModeConfig.DEFAULT_RULE_IDS.contains(id)) { + id = ""; + } + + // Look for packages and enablers, enablers get priority. + String pkg = rule.pkg == null ? "" : rule.pkg; + if (rule.enabler != null) { + pkg = rule.enabler; + id = ZenModeConfig.MANUAL_RULE_ID; + } + + // TODO: fetch the uid from the package manager + int uid = "android".equals(pkg) ? Process.SYSTEM_UID : 0; + + SysUiStatsEvent.Builder data; + data = mStatsEventBuilderFactory.newBuilder() + .setAtomId(DND_MODE_RULE) + .writeInt(user) + .writeBoolean(rule.enabled) + .writeBoolean(false) // channels_bypassing unused for rules + .writeInt(rule.zenMode) + .writeString(id) + .writeInt(uid) + .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true); + byte[] policyProto = new byte[]{}; + if (rule.zenPolicy != null) { + policyProto = rule.zenPolicy.toProto(); + } + data.writeByteArray(policyProto); + events.add(data.build()); + } + @VisibleForTesting protected final class RingerModeDelegate implements AudioManagerInternal.RingerModeDelegate { @Override diff --git a/services/tests/uiservicestests/src/com/android/server/notification/WrappedSysUiStatsEvent.java b/services/tests/uiservicestests/src/com/android/server/notification/WrappedSysUiStatsEvent.java index f4f64d779d304..89adc724f6000 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/WrappedSysUiStatsEvent.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/WrappedSysUiStatsEvent.java @@ -88,11 +88,21 @@ public class WrappedSysUiStatsEvent { return index < mValues.size() ? mValues.get(index) : null; } - /** useful to make assertTrue() statemetns more readable. */ + /** useful to make assertTrue() statements more readable. */ public boolean getBoolean(int index) { return (Boolean) mValues.get(index); } + /** useful to make assertTrue() statements more readable. */ + public int getInt(int index) { + return (Integer) mValues.get(index); + } + + /** useful to make assertTrue() statements more readable. */ + public String getString(int index) { + return (String) mValues.get(index); + } + private void addValue(Object value) { mLastIndex = mValues.size(); mValues.add(value); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java index f7b435ed937bf..013a99433041d 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java @@ -101,10 +101,38 @@ public class ZenModeConfigTest extends UiServiceTestCase { Policy expectedPolicy = new Policy(priorityCategories, priorityCallSenders, priorityMessageSenders, suppressedVisualEffects, 0, priorityConversationsSenders); - assertEquals(expectedPolicy, config.toNotificationPolicy(zenPolicy)); } + @Test + public void testZenConfigToZenPolicy() { + ZenPolicy expected = new ZenPolicy.Builder() + .allowAlarms(true) + .allowReminders(true) + .allowEvents(true) + .showLights(false) + .showBadges(false) + .showInAmbientDisplay(false) + .build(); + + ZenModeConfig config = getMutedAllConfig(); + config.allowAlarms = true; + config.allowReminders = true; + config.allowEvents = true; + config.suppressedVisualEffects |= Policy.SUPPRESSED_EFFECT_BADGE; + config.suppressedVisualEffects |= Policy.SUPPRESSED_EFFECT_LIGHTS; + config.suppressedVisualEffects |= Policy.SUPPRESSED_EFFECT_AMBIENT; + ZenPolicy actual = config.toZenPolicy(); + + assertEquals(expected.getVisualEffectBadge(), actual.getVisualEffectBadge()); + assertEquals(expected.getPriorityCategoryAlarms(), actual.getPriorityCategoryAlarms()); + assertEquals(expected.getPriorityCategoryReminders(), + actual.getPriorityCategoryReminders()); + assertEquals(expected.getPriorityCategoryEvents(), actual.getPriorityCategoryEvents()); + assertEquals(expected.getVisualEffectLights(), actual.getVisualEffectLights()); + assertEquals(expected.getVisualEffectAmbient(), actual.getVisualEffectAmbient()); + } + @Test public void testPriorityOnlyMutingAll() { ZenModeConfig config = getMutedAllConfig(); 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 108af892c7ddf..3c7206fee9d14 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java @@ -27,16 +27,25 @@ import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_REMINDERS import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_REPEAT_CALLERS; import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_SYSTEM; import static android.app.NotificationManager.Policy.PRIORITY_SENDERS_ANY; -import static android.app.NotificationManager.Policy.PRIORITY_SENDERS_CONTACTS; import static android.app.NotificationManager.Policy.PRIORITY_SENDERS_STARRED; import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_BADGE; import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_FULL_SCREEN_INTENT; 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 com.android.internal.util.FrameworkStatsLog.ANNOTATION_ID_IS_UID; +import static com.android.internal.util.FrameworkStatsLog.DND_MODE_RULE; +import static com.android.os.AtomsProto.DNDModeProto.CHANNELS_BYPASSING_FIELD_NUMBER; +import static com.android.os.AtomsProto.DNDModeProto.ENABLED_FIELD_NUMBER; +import static com.android.os.AtomsProto.DNDModeProto.ID_FIELD_NUMBER; +import static com.android.os.AtomsProto.DNDModeProto.UID_FIELD_NUMBER; +import static com.android.os.AtomsProto.DNDModeProto.ZEN_MODE_FIELD_NUMBER; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; import static junit.framework.TestCase.assertTrue; +import static junit.framework.TestCase.fail; import static org.junit.Assert.assertNotEquals; import static org.mockito.ArgumentMatchers.any; @@ -70,10 +79,12 @@ import android.media.AudioManagerInternal; import android.media.AudioSystem; import android.media.VolumePolicy; import android.net.Uri; +import android.os.Process; import android.os.UserHandle; import android.provider.Settings; import android.provider.Settings.Global; import android.service.notification.Condition; +import android.service.notification.DNDModeProto; import android.service.notification.ZenModeConfig; import android.service.notification.ZenModeConfig.ScheduleInfo; import android.service.notification.ZenPolicy; @@ -82,6 +93,7 @@ import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.util.ArrayMap; import android.util.Log; +import android.util.StatsEvent; import android.util.Xml; import com.android.internal.R; @@ -106,6 +118,9 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.Reader; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; import java.util.Objects; @SmallTest @@ -115,6 +130,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { private static final String EVENTS_DEFAULT_RULE_ID = "EVENTS_DEFAULT_RULE"; private static final String SCHEDULE_DEFAULT_RULE_ID = "EVERY_NIGHT_DEFAULT_RULE"; + private static final int ZEN_MODE_FOR_TESTING = 99; ConditionProviders mConditionProviders; @Mock NotificationManager mNotificationManager; @@ -124,6 +140,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { private Context mContext; private ContentResolver mContentResolver; @Mock AppOpsManager mAppOps; + private WrappedSysUiStatsEvent.WrappedBuilderFactory mStatsEventBuilderFactory; @Before public void setUp() { @@ -140,6 +157,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { Log.d("ZenModeHelperTest", "Couldn't mock default zen mode config xml file err=" + e.toString()); } + mStatsEventBuilderFactory = new WrappedSysUiStatsEvent.WrappedBuilderFactory(); when(mContext.getSystemService(AppOpsManager.class)).thenReturn(mAppOps); when(mContext.getSystemService(NotificationManager.class)).thenReturn(mNotificationManager); @@ -147,7 +165,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { AppGlobals.getPackageManager()); mConditionProviders.addSystemProvider(new CountdownConditionProvider()); mZenModeHelperSpy = spy(new ZenModeHelper(mContext, mTestableLooper.getLooper(), - mConditionProviders)); + mConditionProviders, mStatsEventBuilderFactory)); } private XmlResourceParser getDefaultConfigParser() throws IOException, XmlPullParserException { @@ -212,6 +230,10 @@ public class ZenModeHelperTest extends UiServiceTestCase { } private ArrayMap getCustomAutomaticRules() { + return getCustomAutomaticRules(ZEN_MODE_IMPORTANT_INTERRUPTIONS); + } + + private ArrayMap getCustomAutomaticRules(int zenMode) { ArrayMap automaticRules = new ArrayMap<>(); ZenModeConfig.ZenRule customRule = new ZenModeConfig.ZenRule(); final ScheduleInfo customRuleInfo = new ScheduleInfo(); @@ -219,10 +241,10 @@ public class ZenModeHelperTest extends UiServiceTestCase { customRule.creationTime = 0; customRule.id = "customRule"; customRule.name = "Custom Rule"; - customRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; + customRule.zenMode = zenMode; customRule.conditionId = ZenModeConfig.toScheduleConditionId(customRuleInfo); customRule.configurationActivity = - new ComponentName("android", "ScheduleConditionProvider"); + new ComponentName("not.android", "ScheduleConditionProvider"); customRule.pkg = customRule.configurationActivity.getPackageName(); automaticRules.put("customRule", customRule); return automaticRules; @@ -244,7 +266,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { @Test public void testZenOn_NotificationApplied() { - mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; + mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS; // The most permissive policy mZenModeHelperSpy.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS | PRIORITY_CATEGORY_MEDIA | PRIORITY_CATEGORY_MESSAGES @@ -267,7 +289,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { @Test public void testZenOn_StarredCallers_CallTypesBlocked() { - mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; + mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS; // The most permissive policy mZenModeHelperSpy.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS | PRIORITY_CATEGORY_MEDIA | PRIORITY_CATEGORY_MESSAGES @@ -287,7 +309,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { @Test public void testZenOn_AllCallers_CallTypesAllowed() { - mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; + mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS; // The most permissive policy mZenModeHelperSpy.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS | PRIORITY_CATEGORY_MEDIA | PRIORITY_CATEGORY_MESSAGES @@ -307,7 +329,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { @Test public void testZenOn_AllowAlarmsMedia_NoAlarmMediaMuteApplied() { - mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; + mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS; mZenModeHelperSpy.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS | PRIORITY_CATEGORY_MEDIA, 0, 0, 0, 0, 0); @@ -320,7 +342,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { @Test public void testZenOn_DisallowAlarmsMedia_AlarmMediaMuteApplied() { - mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; + mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS; mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0); mZenModeHelperSpy.applyRestrictions(); verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true, true, @@ -406,7 +428,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { public void testZenAllCannotBypass() { // Only audio attributes with SUPPRESIBLE_NEVER can bypass // with special case USAGE_ASSISTANCE_SONIFICATION - mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; + mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS; mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0); mZenModeHelperSpy.applyRestrictions(); @@ -428,7 +450,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { @Test public void testApplyRestrictions_whitelist_priorityOnlyMode() { mZenModeHelperSpy.setPriorityOnlyDndExemptPackages(new String[] {PKG_O}); - mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; + mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS; mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0); mZenModeHelperSpy.applyRestrictions(); @@ -479,7 +501,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_SETTINGS_UPDATED, 0); mZenModeHelperSpy.mIsBootComplete = true; mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0); - mZenModeHelperSpy.setZenModeSetting(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS); + mZenModeHelperSpy.setZenModeSetting(ZEN_MODE_IMPORTANT_INTERRUPTIONS); verify(mZenModeHelperSpy, times(1)).createZenUpgradeNotification(); verify(mNotificationManager, times(1)).notify(eq(ZenModeHelper.TAG), @@ -494,7 +516,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { Settings.Secure.putInt(mContentResolver, Settings.Secure.SHOW_ZEN_UPGRADE_NOTIFICATION, 0); Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_SETTINGS_UPDATED, 0); mZenModeHelperSpy.mIsBootComplete = true; - mZenModeHelperSpy.setZenModeSetting(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS); + mZenModeHelperSpy.setZenModeSetting(ZEN_MODE_IMPORTANT_INTERRUPTIONS); verify(mZenModeHelperSpy, never()).createZenUpgradeNotification(); verify(mNotificationManager, never()).notify(eq(ZenModeHelper.TAG), @@ -507,7 +529,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { Settings.Secure.putInt(mContentResolver, Settings.Secure.SHOW_ZEN_UPGRADE_NOTIFICATION, 0); Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_SETTINGS_UPDATED, 1); mZenModeHelperSpy.mIsBootComplete = true; - mZenModeHelperSpy.setZenModeSetting(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS); + mZenModeHelperSpy.setZenModeSetting(ZEN_MODE_IMPORTANT_INTERRUPTIONS); verify(mZenModeHelperSpy, never()).createZenUpgradeNotification(); verify(mNotificationManager, never()).notify(eq(ZenModeHelper.TAG), @@ -524,7 +546,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { // 1. Current ringer is normal when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL); // Set zen to priority-only with all notification sounds muted (so ringer will be muted) - mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; + mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS; mZenModeHelperSpy.mConfig.allowReminders = false; mZenModeHelperSpy.mConfig.allowCalls = false; mZenModeHelperSpy.mConfig.allowMessages = false; @@ -568,7 +590,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { // ringtone, notification and system streams are affected by ringer mode mZenModeHelperSpy.mConfig.allowAlarms = true; mZenModeHelperSpy.mConfig.allowReminders = true; - mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; + mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS; ZenModeHelper.RingerModeDelegate ringerModeDelegateRingerMuted = mZenModeHelperSpy.new RingerModeDelegate(); @@ -615,7 +637,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { // 1. Current ringer is normal when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL); - mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; + mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS; mZenModeHelperSpy.mConfig.allowReminders = true; // 2. apply priority only zen - verify ringer is normal @@ -640,7 +662,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { // 1. Current ringer is silent when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT); - mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; + mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS; mZenModeHelperSpy.mConfig.allowReminders = true; // 2. apply priority only zen - verify ringer is silent @@ -666,7 +688,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { // 1. Current ringer is normal when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL); // Set zen to priority-only with all notification sounds muted (so ringer will be muted) - mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; + mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS; mZenModeHelperSpy.mConfig.allowReminders = true; // 2. apply priority only zen - verify zen will still be normal @@ -728,7 +750,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { // apply zen off multiple times - verify ringer is not set to normal when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT); - mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; + mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS; for (int i = 0; i < 3; i++) { // if zen doesn't change, zen should not reapply itself to the ringer mZenModeHelperSpy.evaluateZenMode("test", true); @@ -756,7 +778,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { // apply zen off multiple times - verify ringer is not set to normal when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE); - mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; + mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS; for (int i = 0; i < 3; i++) { // if zen doesn't change, zen should not reapply itself to the ringer mZenModeHelperSpy.evaluateZenMode("test", true); @@ -768,7 +790,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { @Test public void testParcelConfig() { - mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; + mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS; mZenModeHelperSpy.mConfig.allowAlarms = false; mZenModeHelperSpy.mConfig.allowMedia = false; mZenModeHelperSpy.mConfig.allowSystem = false; @@ -792,7 +814,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { @Test public void testWriteXml() throws Exception { - mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; + mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS; mZenModeHelperSpy.mConfig.allowAlarms = false; mZenModeHelperSpy.mConfig.allowMedia = false; mZenModeHelperSpy.mConfig.allowSystem = false; @@ -806,7 +828,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { mZenModeHelperSpy.mConfig.suppressedVisualEffects = SUPPRESSED_EFFECT_BADGE; mZenModeHelperSpy.mConfig.manualRule = new ZenModeConfig.ZenRule(); mZenModeHelperSpy.mConfig.manualRule.zenMode = - Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; + ZEN_MODE_IMPORTANT_INTERRUPTIONS; mZenModeHelperSpy.mConfig.manualRule.component = new ComponentName("a", "a"); mZenModeHelperSpy.mConfig.manualRule.pkg = "a"; mZenModeHelperSpy.mConfig.manualRule.enabled = true; @@ -821,6 +843,102 @@ public class ZenModeHelperTest extends UiServiceTestCase { + mZenModeHelperSpy.mConfig.diff(expected), expected, mZenModeHelperSpy.mConfig); } + @Test + public void testProto() { + mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS; + mZenModeHelperSpy.mConfig.manualRule = new ZenModeConfig.ZenRule(); + + int n = mZenModeHelperSpy.mConfig.automaticRules.size(); + List ids = new ArrayList<>(n); + for (ZenModeConfig.ZenRule rule : mZenModeHelperSpy.mConfig.automaticRules.values()) { + ids.add(rule.id); + } + ids.add(""); + + List events = new LinkedList<>(); + mZenModeHelperSpy.pullRules(events); + assertEquals(n + 1, events.size()); + for (WrappedSysUiStatsEvent.WrappedBuilder builder : mStatsEventBuilderFactory.builders) { + if (builder.getAtomId() == DND_MODE_RULE) { + if (builder.getInt(ZEN_MODE_FIELD_NUMBER) == DNDModeProto.ROOT_CONFIG) { + assertTrue(builder.getBoolean(ENABLED_FIELD_NUMBER)); + assertFalse(builder.getBoolean(CHANNELS_BYPASSING_FIELD_NUMBER)); + } + assertEquals(Process.SYSTEM_UID, builder.getInt(UID_FIELD_NUMBER)); + assertTrue(builder.getBooleanAnnotation(UID_FIELD_NUMBER, ANNOTATION_ID_IS_UID)); + String name = (String) builder.getValue(ID_FIELD_NUMBER); + assertTrue("unexpected rule id", ids.contains(name)); + ids.remove(name); + } else { + fail("unexpected atom id: " + builder.getAtomId()); + } + } + assertEquals("extra rule in output", 0, ids.size()); + } + + @Test + public void testProtoWithAutoRule() throws Exception { + setupZenConfig(); + // one enabled automatic rule + mZenModeHelperSpy.mConfig.automaticRules = getCustomAutomaticRules(ZEN_MODE_FOR_TESTING); + + List events = new LinkedList<>(); + mZenModeHelperSpy.pullRules(events); + + boolean foundCustomEvent = false; + for (WrappedSysUiStatsEvent.WrappedBuilder builder : mStatsEventBuilderFactory.builders) { + if (builder.getAtomId() == DND_MODE_RULE) { + if (ZEN_MODE_FOR_TESTING == builder.getInt(ZEN_MODE_FIELD_NUMBER)) { + foundCustomEvent = true; + assertEquals(0, builder.getInt(UID_FIELD_NUMBER)); + assertTrue(builder.getBoolean(ENABLED_FIELD_NUMBER)); + } + } else { + fail("unexpected atom id: " + builder.getAtomId()); + } + } + assertTrue("couldn't find custom rule", foundCustomEvent); + } + + @Test + public void testProtoRedactsIds() throws Exception { + setupZenConfig(); + // one enabled automatic rule + mZenModeHelperSpy.mConfig.automaticRules = getCustomAutomaticRules(); + + List events = new LinkedList<>(); + mZenModeHelperSpy.pullRules(events); + + boolean foundCustomEvent = false; + for (WrappedSysUiStatsEvent.WrappedBuilder builder : mStatsEventBuilderFactory.builders) { + if (builder.getAtomId() == DND_MODE_RULE + && "customRule".equals(builder.getString(ID_FIELD_NUMBER))) { + fail("non-default IDs should be redacted"); + } + } + } + + @Test + public void testProtoWithManualRule() throws Exception { + setupZenConfig(); + mZenModeHelperSpy.mConfig.automaticRules = getCustomAutomaticRules(); + mZenModeHelperSpy.mConfig.manualRule = new ZenModeConfig.ZenRule(); + mZenModeHelperSpy.mConfig.manualRule.enabled = true; + mZenModeHelperSpy.mConfig.manualRule.enabler = "com.enabler"; + + List events = new LinkedList<>(); + mZenModeHelperSpy.pullRules(events); + + boolean foundManualRule = false; + for (WrappedSysUiStatsEvent.WrappedBuilder builder : mStatsEventBuilderFactory.builders) { + if (builder.getAtomId() == DND_MODE_RULE + && ZenModeConfig.MANUAL_RULE_ID.equals(builder.getString(ID_FIELD_NUMBER))) { + assertEquals(0, builder.getInt(UID_FIELD_NUMBER)); + foundManualRule = true; + } + } + assertTrue("couldn't find manual rule", foundManualRule); } + @Test public void testWriteXml_onlyBackupsTargetUser() throws Exception { // Setup configs for user 10 and 11. @@ -906,7 +1024,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { customRule.creationTime = 0; customRule.id = "customRule"; customRule.name = "Custom Rule"; - customRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; + customRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS; customRule.conditionId = ZenModeConfig.toScheduleConditionId(customRuleInfo); customRule.configurationActivity = new ComponentName("android", "ScheduleConditionProvider"); @@ -951,7 +1069,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { customRule.creationTime = 0; customRule.id = ruleId; customRule.name = "Custom Rule"; - customRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; + customRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS; customRule.conditionId = ZenModeConfig.toScheduleConditionId(customRuleInfo); customRule.configurationActivity = new ComponentName("android", "ScheduleConditionProvider"); @@ -986,7 +1104,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { final ScheduleInfo weeknights = new ScheduleInfo(); customRule.enabled = true; customRule.name = "Custom Rule"; - customRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; + customRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS; customRule.conditionId = ZenModeConfig.toScheduleConditionId(weeknights); customRule.component = new ComponentName("android", "ScheduleConditionProvider"); enabledAutoRule.put("customRule", customRule); @@ -1151,7 +1269,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { final ScheduleInfo weeknights = new ScheduleInfo(); customRule.enabled = false; customRule.name = "Custom Rule"; - customRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; + customRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS; customRule.conditionId = ZenModeConfig.toScheduleConditionId(weeknights); customRule.component = new ComponentName("android", "ScheduleConditionProvider"); disabledAutoRule.put("customRule", customRule); @@ -1187,7 +1305,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { final ScheduleInfo customRuleInfo = new ScheduleInfo(); customRule.enabled = false; customRule.name = "Custom Rule"; - customRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; + customRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS; customRule.conditionId = ZenModeConfig.toScheduleConditionId(customRuleInfo); customRule.component = new ComponentName("android", "ScheduleConditionProvider"); customRule.zenPolicy = new ZenPolicy.Builder() @@ -1200,7 +1318,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { final ScheduleInfo defaultScheduleRuleInfo = new ScheduleInfo(); defaultScheduleRule.enabled = false; defaultScheduleRule.name = "Default Schedule Rule"; - defaultScheduleRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; + defaultScheduleRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS; defaultScheduleRule.conditionId = ZenModeConfig.toScheduleConditionId( defaultScheduleRuleInfo); customRule.component = new ComponentName("android", "ScheduleConditionProvider"); @@ -1238,7 +1356,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { final ScheduleInfo customRuleInfo = new ScheduleInfo(); customRule.enabled = false; customRule.name = "Custom Rule"; - customRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; + customRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS; customRule.conditionId = ZenModeConfig.toScheduleConditionId(customRuleInfo); customRule.component = new ComponentName("android", "ScheduleConditionProvider"); customRule.zenPolicy = new ZenPolicy.Builder() @@ -1251,7 +1369,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { final ScheduleInfo defaultScheduleRuleInfo = new ScheduleInfo(); defaultScheduleRule.enabled = false; defaultScheduleRule.name = "Default Schedule Rule"; - defaultScheduleRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; + defaultScheduleRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS; defaultScheduleRule.conditionId = ZenModeConfig.toScheduleConditionId( defaultScheduleRuleInfo); defaultScheduleRule.id = ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID; @@ -1265,7 +1383,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { final ScheduleInfo defaultEventRuleInfo = new ScheduleInfo(); defaultEventRule.enabled = false; defaultEventRule.name = "Default Event Rule"; - defaultEventRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; + defaultEventRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS; defaultEventRule.conditionId = ZenModeConfig.toScheduleConditionId( defaultEventRuleInfo); defaultEventRule.id = ZenModeConfig.EVENTS_DEFAULT_RULE_ID; @@ -1295,6 +1413,10 @@ public class ZenModeHelperTest extends UiServiceTestCase { assertTrue(rules.containsKey("customRule")); setupZenConfigMaintained(); + + List events = new LinkedList<>(); + mZenModeHelperSpy.pullRules(events); + assertEquals(4, events.size()); } @Test @@ -1323,10 +1445,12 @@ public class ZenModeHelperTest extends UiServiceTestCase { @Test public void testEmptyDefaultRulesMap() { + List events = new LinkedList<>(); ZenModeConfig config = new ZenModeConfig(); config.automaticRules = new ArrayMap<>(); mZenModeHelperSpy.mConfig = config; mZenModeHelperSpy.updateDefaultZenRules(); // shouldn't throw null pointer + mZenModeHelperSpy.pullRules(events); // shouldn't throw null pointer } @Test @@ -1342,7 +1466,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { updatedDefaultRule.creationTime = 0; updatedDefaultRule.id = SCHEDULE_DEFAULT_RULE_ID; updatedDefaultRule.name = "Schedule Default Rule"; - updatedDefaultRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; + updatedDefaultRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS; updatedDefaultRule.conditionId = ZenModeConfig.toScheduleConditionId(new ScheduleInfo()); updatedDefaultRule.component = new ComponentName("android", "ScheduleConditionProvider"); @@ -1368,7 +1492,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { updatedDefaultRule.creationTime = 0; updatedDefaultRule.id = SCHEDULE_DEFAULT_RULE_ID; updatedDefaultRule.name = "Schedule Default Rule"; - updatedDefaultRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; + updatedDefaultRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS; updatedDefaultRule.conditionId = ZenModeConfig.toScheduleConditionId(new ScheduleInfo()); updatedDefaultRule.component = new ComponentName("android", "ScheduleConditionProvider"); @@ -1395,7 +1519,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { customDefaultRule.creationTime = 0; customDefaultRule.id = SCHEDULE_DEFAULT_RULE_ID; customDefaultRule.name = "Schedule Default Rule"; - customDefaultRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; + customDefaultRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS; customDefaultRule.conditionId = ZenModeConfig.toScheduleConditionId(new ScheduleInfo()); customDefaultRule.component = new ComponentName("android", "ScheduleConditionProvider"); @@ -1433,7 +1557,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { } private void setupZenConfig() { - mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; + mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS; mZenModeHelperSpy.mConfig.allowAlarms = false; mZenModeHelperSpy.mConfig.allowMedia = false; mZenModeHelperSpy.mConfig.allowSystem = false; diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenPolicyTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenPolicyTest.java index a0ee417c8b473..b16ca8b92848c 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ZenPolicyTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenPolicyTest.java @@ -17,14 +17,18 @@ package com.android.server.notification; import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.fail; import android.service.notification.ZenPolicy; +import android.service.notification.nano.DNDPolicyProto; import android.test.suitebuilder.annotation.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.server.UiServiceTestCase; +import com.google.protobuf.nano.InvalidProtocolBufferNanoException; + import org.junit.Test; import org.junit.runner.RunWith; @@ -190,6 +194,7 @@ public class ZenPolicyTest extends UiServiceTestCase { ZenPolicy policy = builder.build(); assertEquals(ZenPolicy.STATE_UNSET, policy.getPriorityCategoryMessages()); assertEquals(ZenPolicy.PEOPLE_TYPE_UNSET, policy.getPriorityMessageSenders()); + assertProtoMatches(policy, policy.toProto()); } @Test @@ -201,6 +206,7 @@ public class ZenPolicyTest extends UiServiceTestCase { ZenPolicy policy = builder.build(); assertEquals(ZenPolicy.STATE_ALLOW, policy.getPriorityCategoryCalls()); assertEquals(ZenPolicy.PEOPLE_TYPE_ANYONE, policy.getPriorityCallSenders()); + assertProtoMatches(policy, policy.toProto()); } @Test @@ -210,6 +216,7 @@ public class ZenPolicyTest extends UiServiceTestCase { ZenPolicy policy = builder.build(); assertAllPriorityCategoriesUnsetExcept(policy, -1); assertAllVisualEffectsUnsetExcept(policy, -1); + assertProtoMatches(policy, policy.toProto()); } @Test @@ -221,12 +228,14 @@ public class ZenPolicyTest extends UiServiceTestCase { assertAllPriorityCategoriesUnsetExcept(policy, ZenPolicy.PRIORITY_CATEGORY_REMINDERS); assertEquals(ZenPolicy.STATE_ALLOW, policy.getPriorityCategoryReminders()); assertAllVisualEffectsUnsetExcept(policy, -1); + assertProtoMatches(policy, policy.toProto()); builder.allowReminders(false); policy = builder.build(); assertAllPriorityCategoriesUnsetExcept(policy, ZenPolicy.PRIORITY_CATEGORY_REMINDERS); assertEquals(ZenPolicy.STATE_DISALLOW, policy.getPriorityCategoryReminders()); assertAllVisualEffectsUnsetExcept(policy, -1); + assertProtoMatches(policy, policy.toProto()); } @Test @@ -238,12 +247,14 @@ public class ZenPolicyTest extends UiServiceTestCase { assertAllPriorityCategoriesUnsetExcept(policy, ZenPolicy.PRIORITY_CATEGORY_EVENTS); assertEquals(ZenPolicy.STATE_ALLOW, policy.getPriorityCategoryEvents()); assertAllVisualEffectsUnsetExcept(policy, -1); + assertProtoMatches(policy, policy.toProto()); builder.allowEvents(false); policy = builder.build(); assertAllPriorityCategoriesUnsetExcept(policy, ZenPolicy.PRIORITY_CATEGORY_EVENTS); assertEquals(ZenPolicy.STATE_DISALLOW, policy.getPriorityCategoryEvents()); assertAllVisualEffectsUnsetExcept(policy, -1); + assertProtoMatches(policy, policy.toProto()); } @Test @@ -256,6 +267,7 @@ public class ZenPolicyTest extends UiServiceTestCase { assertEquals(ZenPolicy.STATE_ALLOW, policy.getPriorityCategoryMessages()); assertEquals(ZenPolicy.PEOPLE_TYPE_ANYONE, policy.getPriorityMessageSenders()); assertAllVisualEffectsUnsetExcept(policy, -1); + assertProtoMatches(policy, policy.toProto()); builder.allowMessages(ZenPolicy.PEOPLE_TYPE_CONTACTS); policy = builder.build(); @@ -263,6 +275,7 @@ public class ZenPolicyTest extends UiServiceTestCase { assertEquals(ZenPolicy.STATE_ALLOW, policy.getPriorityCategoryMessages()); assertEquals(ZenPolicy.PEOPLE_TYPE_CONTACTS, policy.getPriorityMessageSenders()); assertAllVisualEffectsUnsetExcept(policy, -1); + assertProtoMatches(policy, policy.toProto()); builder.allowMessages(ZenPolicy.PEOPLE_TYPE_STARRED); policy = builder.build(); @@ -270,6 +283,7 @@ public class ZenPolicyTest extends UiServiceTestCase { assertEquals(ZenPolicy.STATE_ALLOW, policy.getPriorityCategoryMessages()); assertEquals(ZenPolicy.PEOPLE_TYPE_STARRED, policy.getPriorityMessageSenders()); assertAllVisualEffectsUnsetExcept(policy, -1); + assertProtoMatches(policy, policy.toProto()); builder.allowMessages(ZenPolicy.PEOPLE_TYPE_NONE); policy = builder.build(); @@ -277,11 +291,13 @@ public class ZenPolicyTest extends UiServiceTestCase { assertEquals(ZenPolicy.STATE_DISALLOW, policy.getPriorityCategoryMessages()); assertEquals(ZenPolicy.PEOPLE_TYPE_NONE, policy.getPriorityMessageSenders()); assertAllVisualEffectsUnsetExcept(policy, -1); + assertProtoMatches(policy, policy.toProto()); builder.allowMessages(ZenPolicy.PEOPLE_TYPE_UNSET); policy = builder.build(); assertAllPriorityCategoriesUnsetExcept(policy, -1); assertAllVisualEffectsUnsetExcept(policy, -1); + assertProtoMatches(policy, policy.toProto()); } @Test @@ -294,6 +310,7 @@ public class ZenPolicyTest extends UiServiceTestCase { assertEquals(ZenPolicy.STATE_ALLOW, policy.getPriorityCategoryCalls()); assertEquals(ZenPolicy.PEOPLE_TYPE_ANYONE, policy.getPriorityCallSenders()); assertAllVisualEffectsUnsetExcept(policy, -1); + assertProtoMatches(policy, policy.toProto()); builder.allowCalls(ZenPolicy.PEOPLE_TYPE_CONTACTS); policy = builder.build(); @@ -301,6 +318,7 @@ public class ZenPolicyTest extends UiServiceTestCase { assertEquals(ZenPolicy.STATE_ALLOW, policy.getPriorityCategoryCalls()); assertEquals(ZenPolicy.PEOPLE_TYPE_CONTACTS, policy.getPriorityCallSenders()); assertAllVisualEffectsUnsetExcept(policy, -1); + assertProtoMatches(policy, policy.toProto()); builder.allowCalls(ZenPolicy.PEOPLE_TYPE_STARRED); policy = builder.build(); @@ -308,6 +326,7 @@ public class ZenPolicyTest extends UiServiceTestCase { assertEquals(ZenPolicy.STATE_ALLOW, policy.getPriorityCategoryCalls()); assertEquals(ZenPolicy.PEOPLE_TYPE_STARRED, policy.getPriorityCallSenders()); assertAllVisualEffectsUnsetExcept(policy, -1); + assertProtoMatches(policy, policy.toProto()); builder.allowCalls(ZenPolicy.PEOPLE_TYPE_NONE); policy = builder.build(); @@ -315,11 +334,13 @@ public class ZenPolicyTest extends UiServiceTestCase { assertEquals(ZenPolicy.STATE_DISALLOW, policy.getPriorityCategoryCalls()); assertEquals(ZenPolicy.PEOPLE_TYPE_NONE, policy.getPriorityCallSenders()); assertAllVisualEffectsUnsetExcept(policy, -1); + assertProtoMatches(policy, policy.toProto()); builder.allowCalls(ZenPolicy.PEOPLE_TYPE_UNSET); policy = builder.build(); assertAllPriorityCategoriesUnsetExcept(policy, -1); assertAllVisualEffectsUnsetExcept(policy, -1); + assertProtoMatches(policy, policy.toProto()); } @Test @@ -331,12 +352,14 @@ public class ZenPolicyTest extends UiServiceTestCase { assertAllPriorityCategoriesUnsetExcept(policy, ZenPolicy.PRIORITY_CATEGORY_REPEAT_CALLERS); assertEquals(ZenPolicy.STATE_ALLOW, policy.getPriorityCategoryRepeatCallers()); assertAllVisualEffectsUnsetExcept(policy, -1); + assertProtoMatches(policy, policy.toProto()); builder.allowRepeatCallers(false); policy = builder.build(); assertAllPriorityCategoriesUnsetExcept(policy, ZenPolicy.PRIORITY_CATEGORY_REPEAT_CALLERS); assertEquals(ZenPolicy.STATE_DISALLOW, policy.getPriorityCategoryRepeatCallers()); assertAllVisualEffectsUnsetExcept(policy, -1); + assertProtoMatches(policy, policy.toProto()); } @Test @@ -348,12 +371,14 @@ public class ZenPolicyTest extends UiServiceTestCase { assertAllPriorityCategoriesUnsetExcept(policy, ZenPolicy.PRIORITY_CATEGORY_ALARMS); assertEquals(ZenPolicy.STATE_ALLOW, policy.getPriorityCategoryAlarms()); assertAllVisualEffectsUnsetExcept(policy, -1); + assertProtoMatches(policy, policy.toProto()); builder.allowAlarms(false); policy = builder.build(); assertAllPriorityCategoriesUnsetExcept(policy, ZenPolicy.PRIORITY_CATEGORY_ALARMS); assertEquals(ZenPolicy.STATE_DISALLOW, policy.getPriorityCategoryAlarms()); assertAllVisualEffectsUnsetExcept(policy, -1); + assertProtoMatches(policy, policy.toProto()); } @Test @@ -365,12 +390,14 @@ public class ZenPolicyTest extends UiServiceTestCase { assertAllPriorityCategoriesUnsetExcept(policy, ZenPolicy.PRIORITY_CATEGORY_MEDIA); assertEquals(ZenPolicy.STATE_ALLOW, policy.getPriorityCategoryMedia()); assertAllVisualEffectsUnsetExcept(policy, -1); + assertProtoMatches(policy, policy.toProto()); builder.allowMedia(false); policy = builder.build(); assertAllPriorityCategoriesUnsetExcept(policy, ZenPolicy.PRIORITY_CATEGORY_MEDIA); assertEquals(ZenPolicy.STATE_DISALLOW, policy.getPriorityCategoryMedia()); assertAllVisualEffectsUnsetExcept(policy, -1); + assertProtoMatches(policy, policy.toProto()); } @Test @@ -382,12 +409,119 @@ public class ZenPolicyTest extends UiServiceTestCase { assertAllPriorityCategoriesUnsetExcept(policy, ZenPolicy.PRIORITY_CATEGORY_SYSTEM); assertEquals(ZenPolicy.STATE_ALLOW, policy.getPriorityCategorySystem()); assertAllVisualEffectsUnsetExcept(policy, -1); + assertProtoMatches(policy, policy.toProto()); builder.allowSystem(false); policy = builder.build(); assertAllPriorityCategoriesUnsetExcept(policy, ZenPolicy.PRIORITY_CATEGORY_SYSTEM); assertEquals(ZenPolicy.STATE_DISALLOW, policy.getPriorityCategorySystem()); assertAllVisualEffectsUnsetExcept(policy, -1); + assertProtoMatches(policy, policy.toProto()); + } + + @Test + public void tesShowFullScreenIntent() { + ZenPolicy.Builder builder = new ZenPolicy.Builder(); + + builder.showFullScreenIntent(true); + ZenPolicy policy = builder.build(); + assertAllVisualEffectsUnsetExcept(policy, ZenPolicy.VISUAL_EFFECT_FULL_SCREEN_INTENT); + assertProtoMatches(policy, policy.toProto()); + + builder.showFullScreenIntent(false); + policy = builder.build(); + assertAllVisualEffectsUnsetExcept(policy, ZenPolicy.VISUAL_EFFECT_FULL_SCREEN_INTENT); + assertProtoMatches(policy, policy.toProto()); + } + + @Test + public void tesShowLights() { + ZenPolicy.Builder builder = new ZenPolicy.Builder(); + + builder.showLights(true); + ZenPolicy policy = builder.build(); + assertAllVisualEffectsUnsetExcept(policy, ZenPolicy.VISUAL_EFFECT_LIGHTS); + assertProtoMatches(policy, policy.toProto()); + + builder.showLights(false); + policy = builder.build(); + assertAllVisualEffectsUnsetExcept(policy, ZenPolicy.VISUAL_EFFECT_LIGHTS); + assertProtoMatches(policy, policy.toProto()); + } + + @Test + public void tesShowPeeking() { + ZenPolicy.Builder builder = new ZenPolicy.Builder(); + + builder.showPeeking(true); + ZenPolicy policy = builder.build(); + assertAllVisualEffectsUnsetExcept(policy, ZenPolicy.VISUAL_EFFECT_PEEK); + assertProtoMatches(policy, policy.toProto()); + + builder.showPeeking(false); + policy = builder.build(); + assertAllVisualEffectsUnsetExcept(policy, ZenPolicy.VISUAL_EFFECT_PEEK); + assertProtoMatches(policy, policy.toProto()); + } + + @Test + public void tesShowStatusBarIcons() { + ZenPolicy.Builder builder = new ZenPolicy.Builder(); + + builder.showStatusBarIcons(true); + ZenPolicy policy = builder.build(); + assertAllVisualEffectsUnsetExcept(policy, ZenPolicy.VISUAL_EFFECT_STATUS_BAR); + assertProtoMatches(policy, policy.toProto()); + + builder.showStatusBarIcons(false); + policy = builder.build(); + assertAllVisualEffectsUnsetExcept(policy, ZenPolicy.VISUAL_EFFECT_STATUS_BAR); + assertProtoMatches(policy, policy.toProto()); + } + + @Test + public void tesShowBadges() { + ZenPolicy.Builder builder = new ZenPolicy.Builder(); + + builder.showBadges(true); + ZenPolicy policy = builder.build(); + assertAllVisualEffectsUnsetExcept(policy, ZenPolicy.VISUAL_EFFECT_BADGE); + assertProtoMatches(policy, policy.toProto()); + + builder.showBadges(false); + policy = builder.build(); + assertAllVisualEffectsUnsetExcept(policy, ZenPolicy.VISUAL_EFFECT_BADGE); + assertProtoMatches(policy, policy.toProto()); + } + + @Test + public void tesShowInAmbientDisplay() { + ZenPolicy.Builder builder = new ZenPolicy.Builder(); + + builder.showInAmbientDisplay(true); + ZenPolicy policy = builder.build(); + assertAllVisualEffectsUnsetExcept(policy, ZenPolicy.VISUAL_EFFECT_AMBIENT); + assertProtoMatches(policy, policy.toProto()); + + builder.showInAmbientDisplay(false); + policy = builder.build(); + assertAllVisualEffectsUnsetExcept(policy, ZenPolicy.VISUAL_EFFECT_AMBIENT); + assertProtoMatches(policy, policy.toProto()); + } + + @Test + public void tesShowInNotificationList() { + ZenPolicy.Builder builder = new ZenPolicy.Builder(); + + builder.showInNotificationList(true); + ZenPolicy policy = builder.build(); + assertAllVisualEffectsUnsetExcept(policy, ZenPolicy.VISUAL_EFFECT_NOTIFICATION_LIST); + assertProtoMatches(policy, policy.toProto()); + + builder.showInNotificationList(false); + policy = builder.build(); + assertAllVisualEffectsUnsetExcept(policy, ZenPolicy.VISUAL_EFFECT_NOTIFICATION_LIST); + assertProtoMatches(policy, policy.toProto()); } private void assertAllPriorityCategoriesUnsetExcept(ZenPolicy policy, int except) { @@ -453,4 +587,35 @@ public class ZenPolicyTest extends UiServiceTestCase { assertEquals(ZenPolicy.STATE_UNSET, policy.getVisualEffectNotificationList()); } } + + private void assertProtoMatches(ZenPolicy policy, byte[] bytes) { + try { + DNDPolicyProto proto = DNDPolicyProto.parseFrom(bytes); + + assertEquals(policy.getPriorityCategoryCalls(), proto.calls); + assertEquals(policy.getPriorityCategoryRepeatCallers(), proto.repeatCallers); + assertEquals(policy.getPriorityCategoryMessages(), proto.messages); + assertEquals(policy.getPriorityCategoryConversations(), proto.conversations); + assertEquals(policy.getPriorityCategoryReminders(), proto.reminders); + assertEquals(policy.getPriorityCategoryEvents(), proto.events); + assertEquals(policy.getPriorityCategoryAlarms(), proto.alarms); + assertEquals(policy.getPriorityCategoryMedia(), proto.media); + assertEquals(policy.getPriorityCategorySystem(), proto.system); + + assertEquals(policy.getVisualEffectFullScreenIntent(), proto.fullscreen); + assertEquals(policy.getVisualEffectLights(), proto.lights); + assertEquals(policy.getVisualEffectPeek(), proto.peek); + assertEquals(policy.getVisualEffectStatusBar(), proto.statusBar); + assertEquals(policy.getVisualEffectBadge(), proto.badge); + assertEquals(policy.getVisualEffectAmbient(), proto.ambient); + assertEquals(policy.getVisualEffectNotificationList(), proto.notificationList); + + assertEquals(policy.getPriorityCallSenders(), proto.allowCallsFrom); + assertEquals(policy.getPriorityMessageSenders(), proto.allowMessagesFrom); + assertEquals(policy.getPriorityConversationSenders(), proto.allowConversationsFrom); + } catch (InvalidProtocolBufferNanoException e) { + fail("could not parse proto bytes"); + } + + } }