Merge "pulled atom for Do Not Disturb configuration" into rvc-dev am: 5599ca731f

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/11494623

Change-Id: Ia2a6641039579516452b2b200b6fbab809e4d885
This commit is contained in:
TreeHugger Robot
2020-06-10 02:48:38 +00:00
committed by Automerger Merge Worker
11 changed files with 679 additions and 42 deletions

View File

@@ -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.

View File

@@ -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<String> 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

View File

@@ -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

View File

@@ -274,4 +274,74 @@ message PackageRemoteViewInfoProto {
// Next Tag: 2
message NotificationRemoteViewsProto {
repeated PackageRemoteViewInfoProto package_remote_view_info = 1;
}
}
/**
* 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;
}

View File

@@ -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;
}

View File

@@ -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 {

View File

@@ -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<Callback> mCallbacks = new ArrayList<Callback>();
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<StatsEvent> 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<StatsEvent> 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

View File

@@ -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);

View File

@@ -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();

View File

@@ -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<String, ZenModeConfig.ZenRule> getCustomAutomaticRules() {
return getCustomAutomaticRules(ZEN_MODE_IMPORTANT_INTERRUPTIONS);
}
private ArrayMap<String, ZenModeConfig.ZenRule> getCustomAutomaticRules(int zenMode) {
ArrayMap<String, ZenModeConfig.ZenRule> 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<String> ids = new ArrayList<>(n);
for (ZenModeConfig.ZenRule rule : mZenModeHelperSpy.mConfig.automaticRules.values()) {
ids.add(rule.id);
}
ids.add("");
List<StatsEvent> 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<StatsEvent> 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<StatsEvent> 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<StatsEvent> 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<StatsEvent> 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<StatsEvent> 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;

View File

@@ -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");
}
}
}