diff options
| -rw-r--r-- | api/current.txt | 2 | ||||
| -rw-r--r-- | api/system-current.txt | 2 | ||||
| -rw-r--r-- | api/test-current.txt | 2 | ||||
| -rw-r--r-- | core/java/android/app/NotificationManager.java | 9 | ||||
| -rw-r--r-- | core/java/android/service/notification/ZenModeConfig.java | 79 | ||||
| -rw-r--r-- | core/res/res/xml/default_zen_mode_config.xml | 2 | ||||
| -rw-r--r-- | media/java/android/media/AudioAttributes.java | 23 | ||||
| -rw-r--r-- | proto/src/metrics_constants.proto | 12 | ||||
| -rw-r--r-- | services/core/java/com/android/server/notification/ZenModeFiltering.java | 21 | ||||
| -rw-r--r-- | services/core/java/com/android/server/notification/ZenModeHelper.java | 24 | ||||
| -rw-r--r-- | services/tests/notification/src/com/android/server/notification/ZenModeHelperTest.java | 104 |
11 files changed, 247 insertions, 33 deletions
diff --git a/api/current.txt b/api/current.txt index a2e242d68351..93cc84362fd5 100644 --- a/api/current.txt +++ b/api/current.txt @@ -5644,8 +5644,10 @@ package android.app { method public static java.lang.String suppressedEffectsToString(int); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.app.NotificationManager.Policy> CREATOR; + field public static final int PRIORITY_CATEGORY_ALARMS = 32; // 0x20 field public static final int PRIORITY_CATEGORY_CALLS = 8; // 0x8 field public static final int PRIORITY_CATEGORY_EVENTS = 2; // 0x2 + field public static final int PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER = 64; // 0x40 field public static final int PRIORITY_CATEGORY_MESSAGES = 4; // 0x4 field public static final int PRIORITY_CATEGORY_REMINDERS = 1; // 0x1 field public static final int PRIORITY_CATEGORY_REPEAT_CALLERS = 16; // 0x10 diff --git a/api/system-current.txt b/api/system-current.txt index 1e2ce4fa988e..9767e441453b 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -5852,8 +5852,10 @@ package android.app { method public static java.lang.String suppressedEffectsToString(int); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.app.NotificationManager.Policy> CREATOR; + field public static final int PRIORITY_CATEGORY_ALARMS = 32; // 0x20 field public static final int PRIORITY_CATEGORY_CALLS = 8; // 0x8 field public static final int PRIORITY_CATEGORY_EVENTS = 2; // 0x2 + field public static final int PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER = 64; // 0x40 field public static final int PRIORITY_CATEGORY_MESSAGES = 4; // 0x4 field public static final int PRIORITY_CATEGORY_REMINDERS = 1; // 0x1 field public static final int PRIORITY_CATEGORY_REPEAT_CALLERS = 16; // 0x10 diff --git a/api/test-current.txt b/api/test-current.txt index 3c6144830f4f..702ec3bacf05 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -5670,8 +5670,10 @@ package android.app { method public static java.lang.String suppressedEffectsToString(int); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.app.NotificationManager.Policy> CREATOR; + field public static final int PRIORITY_CATEGORY_ALARMS = 32; // 0x20 field public static final int PRIORITY_CATEGORY_CALLS = 8; // 0x8 field public static final int PRIORITY_CATEGORY_EVENTS = 2; // 0x2 + field public static final int PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER = 64; // 0x40 field public static final int PRIORITY_CATEGORY_MESSAGES = 4; // 0x4 field public static final int PRIORITY_CATEGORY_REMINDERS = 1; // 0x1 field public static final int PRIORITY_CATEGORY_REPEAT_CALLERS = 16; // 0x10 diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java index eb52cb7f9508..a52dc1e4e768 100644 --- a/core/java/android/app/NotificationManager.java +++ b/core/java/android/app/NotificationManager.java @@ -934,8 +934,14 @@ public class NotificationManager { public static final int PRIORITY_CATEGORY_CALLS = 1 << 3; /** Calls from repeat callers are prioritized. */ public static final int PRIORITY_CATEGORY_REPEAT_CALLERS = 1 << 4; + /** Alarms are prioritized */ + public static final int PRIORITY_CATEGORY_ALARMS = 1 << 5; + /** Media, system, game (catch-all for non-never suppressible sounds) are prioritized */ + public static final int PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER = 1 << 6; private static final int[] ALL_PRIORITY_CATEGORIES = { + PRIORITY_CATEGORY_ALARMS, + PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER, PRIORITY_CATEGORY_REMINDERS, PRIORITY_CATEGORY_EVENTS, PRIORITY_CATEGORY_MESSAGES, @@ -1135,6 +1141,9 @@ public class NotificationManager { case PRIORITY_CATEGORY_MESSAGES: return "PRIORITY_CATEGORY_MESSAGES"; case PRIORITY_CATEGORY_CALLS: return "PRIORITY_CATEGORY_CALLS"; case PRIORITY_CATEGORY_REPEAT_CALLERS: return "PRIORITY_CATEGORY_REPEAT_CALLERS"; + case PRIORITY_CATEGORY_ALARMS: return "PRIORITY_CATEGORY_ALARMS"; + case PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER: + return "PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER"; default: return "PRIORITY_CATEGORY_UNKNOWN_" + priorityCategory; } } diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java index 7bec898ac347..c5615ae6f8dc 100644 --- a/core/java/android/service/notification/ZenModeConfig.java +++ b/core/java/android/service/notification/ZenModeConfig.java @@ -76,10 +76,13 @@ public class ZenModeConfig implements Parcelable { private static final int DAY_MINUTES = 24 * 60; private static final int ZERO_VALUE_MS = 10 * SECONDS_MS; - private static final boolean DEFAULT_ALLOW_CALLS = true; + // Default allow categories set in readXml() from default_zen_mode_config.xml, fallback values: + private static final boolean DEFAULT_ALLOW_ALARMS = true; + private static final boolean DEFAULT_ALLOW_MEDIA_SYSTEM_OTHER = true; + private static final boolean DEFAULT_ALLOW_CALLS = false; private static final boolean DEFAULT_ALLOW_MESSAGES = false; - private static final boolean DEFAULT_ALLOW_REMINDERS = true; - private static final boolean DEFAULT_ALLOW_EVENTS = true; + private static final boolean DEFAULT_ALLOW_REMINDERS = false; + private static final boolean DEFAULT_ALLOW_EVENTS = false; private static final boolean DEFAULT_ALLOW_REPEAT_CALLERS = false; private static final boolean DEFAULT_ALLOW_SCREEN_OFF = true; private static final boolean DEFAULT_ALLOW_SCREEN_ON = true; @@ -89,6 +92,8 @@ public class ZenModeConfig implements Parcelable { private static final String ZEN_ATT_VERSION = "version"; private static final String ZEN_ATT_USER = "user"; private static final String ALLOW_TAG = "allow"; + private static final String ALLOW_ATT_ALARMS = "alarms"; + private static final String ALLOW_ATT_MEDIA = "media_system_other"; private static final String ALLOW_ATT_CALLS = "calls"; private static final String ALLOW_ATT_REPEAT_CALLERS = "repeatCallers"; private static final String ALLOW_ATT_MESSAGES = "messages"; @@ -100,8 +105,6 @@ public class ZenModeConfig implements Parcelable { private static final String ALLOW_ATT_SCREEN_OFF = "visualScreenOff"; private static final String ALLOW_ATT_SCREEN_ON = "visualScreenOn"; - private static final String CONDITION_TAG = "condition"; - private static final String CONDITION_ATT_COMPONENT = "component"; private static final String CONDITION_ATT_ID = "id"; private static final String CONDITION_ATT_SUMMARY = "summary"; private static final String CONDITION_ATT_LINE1 = "line1"; @@ -123,6 +126,8 @@ public class ZenModeConfig implements Parcelable { private static final String RULE_ATT_CREATION_TIME = "creationTime"; private static final String RULE_ATT_ENABLER = "enabler"; + public boolean allowAlarms = DEFAULT_ALLOW_ALARMS; + public boolean allowMediaSystemOther = DEFAULT_ALLOW_MEDIA_SYSTEM_OTHER; public boolean allowCalls = DEFAULT_ALLOW_CALLS; public boolean allowRepeatCallers = DEFAULT_ALLOW_REPEAT_CALLERS; public boolean allowMessages = DEFAULT_ALLOW_MESSAGES; @@ -161,6 +166,8 @@ public class ZenModeConfig implements Parcelable { } allowWhenScreenOff = source.readInt() == 1; allowWhenScreenOn = source.readInt() == 1; + allowAlarms = source.readInt() == 1; + allowMediaSystemOther = source.readInt() == 1; } @Override @@ -190,19 +197,23 @@ public class ZenModeConfig implements Parcelable { } dest.writeInt(allowWhenScreenOff ? 1 : 0); dest.writeInt(allowWhenScreenOn ? 1 : 0); + dest.writeInt(allowAlarms ? 1 : 0); + dest.writeInt(allowMediaSystemOther ? 1 : 0); } @Override public String toString() { return new StringBuilder(ZenModeConfig.class.getSimpleName()).append('[') .append("user=").append(user) + .append(",allowAlarms=").append(allowAlarms) + .append(",allowMediaSystemOther=").append(allowMediaSystemOther) + .append(",allowReminders=").append(allowReminders) + .append(",allowEvents=").append(allowEvents) .append(",allowCalls=").append(allowCalls) .append(",allowRepeatCallers=").append(allowRepeatCallers) .append(",allowMessages=").append(allowMessages) .append(",allowCallsFrom=").append(sourceToString(allowCallsFrom)) .append(",allowMessagesFrom=").append(sourceToString(allowMessagesFrom)) - .append(",allowReminders=").append(allowReminders) - .append(",allowEvents=").append(allowEvents) .append(",allowWhenScreenOff=").append(allowWhenScreenOff) .append(",allowWhenScreenOn=").append(allowWhenScreenOn) .append(",automaticRules=").append(automaticRules) @@ -218,9 +229,21 @@ public class ZenModeConfig implements Parcelable { if (user != to.user) { d.addLine("user", user, to.user); } + if (allowAlarms != to.allowAlarms) { + d.addLine("allowAlarms", allowAlarms, to.allowAlarms); + } + if (allowMediaSystemOther != to.allowMediaSystemOther) { + d.addLine("allowMediaSystemOther", allowMediaSystemOther, to.allowMediaSystemOther); + } if (allowCalls != to.allowCalls) { d.addLine("allowCalls", allowCalls, to.allowCalls); } + if (allowReminders != to.allowReminders) { + d.addLine("allowReminders", allowReminders, to.allowReminders); + } + if (allowEvents != to.allowEvents) { + d.addLine("allowEvents", allowEvents, to.allowEvents); + } if (allowRepeatCallers != to.allowRepeatCallers) { d.addLine("allowRepeatCallers", allowRepeatCallers, to.allowRepeatCallers); } @@ -233,12 +256,6 @@ public class ZenModeConfig implements Parcelable { if (allowMessagesFrom != to.allowMessagesFrom) { d.addLine("allowMessagesFrom", allowMessagesFrom, to.allowMessagesFrom); } - if (allowReminders != to.allowReminders) { - d.addLine("allowReminders", allowReminders, to.allowReminders); - } - if (allowEvents != to.allowEvents) { - d.addLine("allowEvents", allowEvents, to.allowEvents); - } if (allowWhenScreenOff != to.allowWhenScreenOff) { d.addLine("allowWhenScreenOff", allowWhenScreenOff, to.allowWhenScreenOff); } @@ -335,7 +352,9 @@ public class ZenModeConfig implements Parcelable { if (!(o instanceof ZenModeConfig)) return false; if (o == this) return true; final ZenModeConfig other = (ZenModeConfig) o; - return other.allowCalls == allowCalls + return other.allowAlarms == allowAlarms + && other.allowMediaSystemOther == allowMediaSystemOther + && other.allowCalls == allowCalls && other.allowRepeatCallers == allowRepeatCallers && other.allowMessages == allowMessages && other.allowCallsFrom == allowCallsFrom @@ -351,10 +370,10 @@ public class ZenModeConfig implements Parcelable { @Override public int hashCode() { - return Objects.hash(allowCalls, allowRepeatCallers, allowMessages, allowCallsFrom, - allowMessagesFrom, allowReminders, allowEvents, allowWhenScreenOff, - allowWhenScreenOn, - user, automaticRules, manualRule); + return Objects.hash(allowAlarms, allowMediaSystemOther, allowCalls, + allowRepeatCallers, allowMessages, + allowCallsFrom, allowMessagesFrom, allowReminders, allowEvents, + allowWhenScreenOff, allowWhenScreenOn, user, automaticRules, manualRule); } private static String toDayList(int[] days) { @@ -413,10 +432,12 @@ public class ZenModeConfig implements Parcelable { } if (type == XmlPullParser.START_TAG) { if (ALLOW_TAG.equals(tag)) { - rt.allowCalls = safeBoolean(parser, ALLOW_ATT_CALLS, false); + rt.allowCalls = safeBoolean(parser, ALLOW_ATT_CALLS, + DEFAULT_ALLOW_CALLS); rt.allowRepeatCallers = safeBoolean(parser, ALLOW_ATT_REPEAT_CALLERS, DEFAULT_ALLOW_REPEAT_CALLERS); - rt.allowMessages = safeBoolean(parser, ALLOW_ATT_MESSAGES, false); + rt.allowMessages = safeBoolean(parser, ALLOW_ATT_MESSAGES, + DEFAULT_ALLOW_MESSAGES); rt.allowReminders = safeBoolean(parser, ALLOW_ATT_REMINDERS, DEFAULT_ALLOW_REMINDERS); rt.allowEvents = safeBoolean(parser, ALLOW_ATT_EVENTS, DEFAULT_ALLOW_EVENTS); @@ -438,6 +459,9 @@ public class ZenModeConfig implements Parcelable { safeBoolean(parser, ALLOW_ATT_SCREEN_OFF, DEFAULT_ALLOW_SCREEN_OFF); rt.allowWhenScreenOn = safeBoolean(parser, ALLOW_ATT_SCREEN_ON, DEFAULT_ALLOW_SCREEN_ON); + rt.allowAlarms = safeBoolean(parser, ALLOW_ATT_ALARMS, DEFAULT_ALLOW_ALARMS); + rt.allowMediaSystemOther = safeBoolean(parser, ALLOW_ATT_MEDIA, + DEFAULT_ALLOW_MEDIA_SYSTEM_OTHER); } else if (MANUAL_TAG.equals(tag)) { rt.manualRule = readRuleXml(parser); } else if (AUTOMATIC_TAG.equals(tag)) { @@ -468,6 +492,8 @@ public class ZenModeConfig implements Parcelable { out.attribute(null, ALLOW_ATT_MESSAGES_FROM, Integer.toString(allowMessagesFrom)); out.attribute(null, ALLOW_ATT_SCREEN_OFF, Boolean.toString(allowWhenScreenOff)); out.attribute(null, ALLOW_ATT_SCREEN_ON, Boolean.toString(allowWhenScreenOn)); + out.attribute(null, ALLOW_ATT_ALARMS, Boolean.toString(allowAlarms)); + out.attribute(null, ALLOW_ATT_ALARMS, Boolean.toString(allowMediaSystemOther)); out.endTag(null, ALLOW_TAG); if (manualRule != null) { @@ -654,6 +680,12 @@ public class ZenModeConfig implements Parcelable { if (!allowWhenScreenOn) { suppressedVisualEffects |= Policy.SUPPRESSED_EFFECT_SCREEN_ON; } + if (allowAlarms) { + priorityCategories |= Policy.PRIORITY_CATEGORY_ALARMS; + } + if (allowMediaSystemOther) { + priorityCategories |= Policy.PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER; + } priorityCallSenders = sourceToPrioritySenders(allowCallsFrom, priorityCallSenders); priorityMessageSenders = sourceToPrioritySenders(allowMessagesFrom, priorityMessageSenders); return new Policy(priorityCategories, priorityCallSenders, priorityMessageSenders, @@ -680,10 +712,13 @@ public class ZenModeConfig implements Parcelable { public void applyNotificationPolicy(Policy policy) { if (policy == null) return; - allowCalls = (policy.priorityCategories & Policy.PRIORITY_CATEGORY_CALLS) != 0; - allowMessages = (policy.priorityCategories & Policy.PRIORITY_CATEGORY_MESSAGES) != 0; + allowAlarms = (policy.priorityCategories & Policy.PRIORITY_CATEGORY_ALARMS) != 0; + allowMediaSystemOther = (policy.priorityCategories + & Policy.PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER) != 0; allowEvents = (policy.priorityCategories & Policy.PRIORITY_CATEGORY_EVENTS) != 0; allowReminders = (policy.priorityCategories & Policy.PRIORITY_CATEGORY_REMINDERS) != 0; + allowCalls = (policy.priorityCategories & Policy.PRIORITY_CATEGORY_CALLS) != 0; + allowMessages = (policy.priorityCategories & Policy.PRIORITY_CATEGORY_MESSAGES) != 0; allowRepeatCallers = (policy.priorityCategories & Policy.PRIORITY_CATEGORY_REPEAT_CALLERS) != 0; allowCallsFrom = prioritySendersToSource(policy.priorityCallSenders, allowCallsFrom); diff --git a/core/res/res/xml/default_zen_mode_config.xml b/core/res/res/xml/default_zen_mode_config.xml index 5f4199acfe7e..1e4c03ee9637 100644 --- a/core/res/res/xml/default_zen_mode_config.xml +++ b/core/res/res/xml/default_zen_mode_config.xml @@ -19,5 +19,5 @@ <!-- Default configuration for zen mode. See android.service.notification.ZenModeConfig. --> <zen version="2"> - <allow calls="true" messages="false" reminders="true" events="true" /> + <allow alarms="true" media_system_other="true" calls="false" messages="false" reminders="false" events="false" /> </zen> diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java index 26ead3d1b54d..20405d3b725c 100644 --- a/media/java/android/media/AudioAttributes.java +++ b/media/java/android/media/AudioAttributes.java @@ -202,6 +202,22 @@ public final class AudioAttributes implements Parcelable { * @see #SUPPRESSIBLE_USAGES */ public final static int SUPPRESSIBLE_NEVER = 3; + /** + * @hide + * Denotes a usage for alarms, + * will be muted when the Zen mode doesn't allow alarms + * @see #SUPPRESSIBLE_USAGES + */ + public final static int SUPPRESSIBLE_ALARM = 4; + /** + * @hide + * Denotes a usage for all other sounds not caught in SUPPRESSIBLE_NOTIFICATION, + * SUPPRESSIBLE_CALL,SUPPRESSIBLE_NEVER or SUPPRESSIBLE_ALARM. + * This includes media, system, game, navigation, the assistant, and more. + * These will be muted when the Zen mode doesn't allow media/system/other. + * @see #SUPPRESSIBLE_USAGES + */ + public final static int SUPPRESSIBLE_MEDIA_SYSTEM_OTHER = 5; /** * @hide @@ -221,6 +237,13 @@ public final class AudioAttributes implements Parcelable { SUPPRESSIBLE_USAGES.put(USAGE_NOTIFICATION_EVENT, SUPPRESSIBLE_NOTIFICATION); SUPPRESSIBLE_USAGES.put(USAGE_ASSISTANCE_ACCESSIBILITY, SUPPRESSIBLE_NEVER); SUPPRESSIBLE_USAGES.put(USAGE_VOICE_COMMUNICATION, SUPPRESSIBLE_NEVER); + SUPPRESSIBLE_USAGES.put(USAGE_ALARM, SUPPRESSIBLE_ALARM); + SUPPRESSIBLE_USAGES.put(USAGE_MEDIA, SUPPRESSIBLE_MEDIA_SYSTEM_OTHER); + SUPPRESSIBLE_USAGES.put(USAGE_ASSISTANCE_SONIFICATION, SUPPRESSIBLE_MEDIA_SYSTEM_OTHER); + SUPPRESSIBLE_USAGES.put(USAGE_ASSISTANCE_NAVIGATION_GUIDANCE, SUPPRESSIBLE_MEDIA_SYSTEM_OTHER); + SUPPRESSIBLE_USAGES.put(USAGE_GAME, SUPPRESSIBLE_MEDIA_SYSTEM_OTHER); + SUPPRESSIBLE_USAGES.put(USAGE_VOICE_COMMUNICATION_SIGNALLING, SUPPRESSIBLE_MEDIA_SYSTEM_OTHER); + SUPPRESSIBLE_USAGES.put(USAGE_ASSISTANT, SUPPRESSIBLE_MEDIA_SYSTEM_OTHER); } /** diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto index 6a8a222254db..9b167c82be6d 100644 --- a/proto/src/metrics_constants.proto +++ b/proto/src/metrics_constants.proto @@ -4675,6 +4675,18 @@ message MetricsEvent { // OS: P DIALOG_LOG_PERSIST = 1225; + // ACTION: DND Settings > Priority only allows > Alarms toggle + // SUBTYPE: 0 is off, 1 is on + // CATEGORY: SETTINGS + // OS: P + ACTION_ZEN_ALLOW_ALARMS = 1162; + + // ACTION: DND Settings > Priority only allows > Media toggle + // SUBTYPE: 0 is off, 1 is on + // CATEGORY: SETTINGS + // OS: P + ACTION_ZEN_ALLOW_MEDIA = 1163; + // Add new aosp constants above this line. // END OF AOSP CONSTANTS } diff --git a/services/core/java/com/android/server/notification/ZenModeFiltering.java b/services/core/java/com/android/server/notification/ZenModeFiltering.java index a7a2743dfc7f..abf2900654fd 100644 --- a/services/core/java/com/android/server/notification/ZenModeFiltering.java +++ b/services/core/java/com/android/server/notification/ZenModeFiltering.java @@ -117,15 +117,19 @@ public class ZenModeFiltering { ZenLog.traceIntercepted(record, "alarmsOnly"); return true; case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS: - if (isAlarm(record)) { - // Alarms are always priority - return false; - } // allow user-prioritized packages through in priority mode if (record.getPackagePriority() == Notification.PRIORITY_MAX) { ZenLog.traceNotIntercepted(record, "priorityApp"); return false; } + + if (isAlarm(record)) { + if (!config.allowAlarms) { + ZenLog.traceIntercepted(record, "!allowAlarms"); + return true; + } + return false; + } if (isCall(record)) { if (config.allowRepeatCallers && REPEAT_CALLERS.isRepeat(mContext, extras(record))) { @@ -159,6 +163,15 @@ public class ZenModeFiltering { } return false; } + AudioAttributes aa = record.getAudioAttributes(); + if (aa != null && AudioAttributes.SUPPRESSIBLE_USAGES.get(aa.getUsage()) == + AudioAttributes.SUPPRESSIBLE_MEDIA_SYSTEM_OTHER) { + if (!config.allowMediaSystemOther) { + ZenLog.traceIntercepted(record, "!allowMediaSystemOther"); + return true; + } + return false; + } ZenLog.traceIntercepted(record, "!priority"); return true; default: diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java index 9fcc67df500a..710684f4351d 100644 --- a/services/core/java/com/android/server/notification/ZenModeHelper.java +++ b/services/core/java/com/android/server/notification/ZenModeHelper.java @@ -59,6 +59,7 @@ import android.util.SparseArray; import android.util.proto.ProtoOutputStream; import com.android.internal.R; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; import com.android.server.LocalServices; @@ -87,7 +88,7 @@ public class ZenModeHelper { private final Context mContext; private final H mHandler; private final SettingsObserver mSettingsObserver; - private final AppOpsManager mAppOps; + @VisibleForTesting protected final AppOpsManager mAppOps; protected ZenModeConfig mDefaultConfig; private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>(); private final ZenModeFiltering mFiltering; @@ -102,9 +103,9 @@ public class ZenModeHelper { private final String SCHEDULED_DEFAULT_RULE_1 = "SCHEDULED_DEFAULT_RULE_1"; private final String SCHEDULED_DEFAULT_RULE_2 = "SCHEDULED_DEFAULT_RULE_2"; - private int mZenMode; + @VisibleForTesting protected int mZenMode; private int mUser = UserHandle.USER_SYSTEM; - protected ZenModeConfig mConfig; + @VisibleForTesting protected ZenModeConfig mConfig; private AudioManagerInternal mAudioManager; protected PackageManager mPm; private long mSuppressedEffects; @@ -595,8 +596,9 @@ public class ZenModeHelper { pw.println(config); return; } - pw.printf("allow(calls=%b,callsFrom=%s,repeatCallers=%b,messages=%b,messagesFrom=%s," + pw.printf("allow(alarms=%b,media=%bcalls=%b,callsFrom=%s,repeatCallers=%b,messages=%b,messagesFrom=%s," + "events=%b,reminders=%b,whenScreenOff=%b,whenScreenOn=%b)\n", + config.allowAlarms, config.allowMediaSystemOther, config.allowCalls, ZenModeConfig.sourceToString(config.allowCallsFrom), config.allowRepeatCallers, config.allowMessages, ZenModeConfig.sourceToString(config.allowMessagesFrom), @@ -813,7 +815,8 @@ public class ZenModeHelper { } } - private void applyRestrictions() { + @VisibleForTesting + protected void applyRestrictions() { final boolean zen = mZenMode != Global.ZEN_MODE_OFF; // notification restrictions @@ -822,6 +825,10 @@ public class ZenModeHelper { // call restrictions final boolean muteCalls = zen && !mConfig.allowCalls && !mConfig.allowRepeatCallers || (mSuppressedEffects & SUPPRESSED_EFFECT_CALLS) != 0; + // alarm restrictions + final boolean muteAlarms = zen && !mConfig.allowAlarms; + // alarm restrictions + final boolean muteMediaAndSystemSounds = zen && !mConfig.allowMediaSystemOther; // total silence restrictions final boolean muteEverything = mZenMode == Global.ZEN_MODE_NO_INTERRUPTIONS; @@ -833,13 +840,18 @@ public class ZenModeHelper { applyRestrictions(muteNotifications || muteEverything, usage); } else if (suppressionBehavior == AudioAttributes.SUPPRESSIBLE_CALL) { applyRestrictions(muteCalls || muteEverything, usage); + } else if (suppressionBehavior == AudioAttributes.SUPPRESSIBLE_ALARM) { + applyRestrictions(muteAlarms || muteEverything, usage); + } else if (suppressionBehavior == AudioAttributes.SUPPRESSIBLE_MEDIA_SYSTEM_OTHER) { + applyRestrictions(muteMediaAndSystemSounds || muteEverything, usage); } else { applyRestrictions(muteEverything, usage); } } } - private void applyRestrictions(boolean mute, int usage) { + @VisibleForTesting + protected void applyRestrictions(boolean mute, int usage) { final String[] exceptionPackages = null; // none (for now) mAppOps.setRestriction(AppOpsManager.OP_VIBRATE, usage, mute ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED, diff --git a/services/tests/notification/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/notification/src/com/android/server/notification/ZenModeHelperTest.java new file mode 100644 index 000000000000..cbe9650edc43 --- /dev/null +++ b/services/tests/notification/src/com/android/server/notification/ZenModeHelperTest.java @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distriZenbuted on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.notification; + +import static junit.framework.Assert.assertFalse; +import static junit.framework.Assert.assertTrue; + +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; + +import android.media.AudioAttributes; +import android.provider.Settings; +import android.test.suitebuilder.annotation.SmallTest; +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +@SmallTest +@RunWith(AndroidTestingRunner.class) +@TestableLooper.RunWithLooper +public class ZenModeHelperTest extends NotificationTestCase { + + @Mock ConditionProviders mConditionProviders; + private TestableLooper mTestableLooper; + private ZenModeHelper mZenModeHelperSpy; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + mTestableLooper = TestableLooper.get(this); + mZenModeHelperSpy = spy(new ZenModeHelper(getContext(), mTestableLooper.getLooper(), + mConditionProviders)); + } + + @Test + public void testZenOff_NoMuteApplied() { + mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_OFF; + assertTrue(mZenModeHelperSpy.mConfig.allowAlarms); + mZenModeHelperSpy.applyRestrictions(); + + doNothing().when(mZenModeHelperSpy).applyRestrictions(anyBoolean(), anyInt()); + verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, + AudioAttributes.USAGE_ALARM); + verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, + AudioAttributes.USAGE_MEDIA); + } + + @Test + public void testZenOn_AllowAlarmsMedia_NoAlarmMediaMuteApplied() { + mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; + assertTrue(mZenModeHelperSpy.mConfig.allowAlarms); + assertTrue(mZenModeHelperSpy.mConfig.allowMediaSystemOther); + mZenModeHelperSpy.applyRestrictions(); + verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, + AudioAttributes.USAGE_ALARM); + verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, + AudioAttributes.USAGE_MEDIA); + } + + @Test + public void testZenOn_DisallowAlarmsMedia_AlarmMediaMuteApplied() { + + mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; + mZenModeHelperSpy.mConfig.allowAlarms = false; + mZenModeHelperSpy.mConfig.allowMediaSystemOther = false; + assertFalse(mZenModeHelperSpy.mConfig.allowAlarms); + assertFalse(mZenModeHelperSpy.mConfig.allowMediaSystemOther); + mZenModeHelperSpy.applyRestrictions(); + verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true, + AudioAttributes.USAGE_ALARM); + + // Media is a catch-all that includes games and system sounds + verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true, + AudioAttributes.USAGE_MEDIA); + verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true, + AudioAttributes.USAGE_GAME); + verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true, + AudioAttributes.USAGE_ASSISTANCE_SONIFICATION); + } +} |