diff --git a/api/current.txt b/api/current.txt index 01117c9c27161..312345511391d 100644 --- a/api/current.txt +++ b/api/current.txt @@ -5744,10 +5744,11 @@ package android.app { 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_MEDIA = 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 + field public static final int PRIORITY_CATEGORY_SYSTEM = 128; // 0x80 field public static final int PRIORITY_SENDERS_ANY = 0; // 0x0 field public static final int PRIORITY_SENDERS_CONTACTS = 1; // 0x1 field public static final int PRIORITY_SENDERS_STARRED = 2; // 0x2 diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java index b10e60870721a..b207d57689c40 100644 --- a/core/java/android/app/NotificationManager.java +++ b/core/java/android/app/NotificationManager.java @@ -1031,12 +1031,18 @@ public class NotificationManager { 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; + /** Media, game, voice navigation are prioritized */ + public static final int PRIORITY_CATEGORY_MEDIA = 1 << 6; + /**System (catch-all for non-never suppressible sounds) are prioritized */ + public static final int PRIORITY_CATEGORY_SYSTEM = 1 << 7; - private static final int[] ALL_PRIORITY_CATEGORIES = { + /** + * @hide + */ + public static final int[] ALL_PRIORITY_CATEGORIES = { PRIORITY_CATEGORY_ALARMS, - PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER, + PRIORITY_CATEGORY_MEDIA, + PRIORITY_CATEGORY_SYSTEM, PRIORITY_CATEGORY_REMINDERS, PRIORITY_CATEGORY_EVENTS, PRIORITY_CATEGORY_MESSAGES, @@ -1237,8 +1243,8 @@ public class NotificationManager { 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"; + case PRIORITY_CATEGORY_MEDIA: return "PRIORITY_CATEGORY_MEDIA"; + case PRIORITY_CATEGORY_SYSTEM: return "PRIORITY_CATEGORY_SYSTEM"; default: return "PRIORITY_CATEGORY_UNKNOWN_" + priorityCategory; } } diff --git a/core/java/android/preference/SeekBarVolumizer.java b/core/java/android/preference/SeekBarVolumizer.java index d774281937491..0ed252667533c 100644 --- a/core/java/android/preference/SeekBarVolumizer.java +++ b/core/java/android/preference/SeekBarVolumizer.java @@ -90,7 +90,7 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba private NotificationManager.Policy mNotificationPolicy; private boolean mAllowAlarms; - private boolean mAllowMediaSystem; + private boolean mAllowMedia; private boolean mAllowRinger; public SeekBarVolumizer(Context context, int streamType, Uri defaultUri, Callback callback) { @@ -100,8 +100,8 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba mNotificationPolicy = mNotificationManager.getNotificationPolicy(); mAllowAlarms = (mNotificationPolicy.priorityCategories & NotificationManager.Policy .PRIORITY_CATEGORY_ALARMS) != 0; - mAllowMediaSystem = (mNotificationPolicy.priorityCategories & NotificationManager.Policy - .PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER) != 0; + mAllowMedia = (mNotificationPolicy.priorityCategories & NotificationManager.Policy + .PRIORITY_CATEGORY_MEDIA) != 0; mAllowRinger = !ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted( mNotificationPolicy); mStreamType = streamType; @@ -139,8 +139,8 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba return stream == AudioManager.STREAM_ALARM; } - private static boolean isMediaOrSystemStream(int stream) { - return stream == AudioManager.STREAM_MUSIC || stream == AudioManager.STREAM_SYSTEM; + private static boolean isMediaStream(int stream) { + return stream == AudioManager.STREAM_MUSIC; } public void setSeekBar(SeekBar seekBar) { @@ -159,7 +159,7 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba || mZenMode == Global.ZEN_MODE_NO_INTERRUPTIONS || (mZenMode == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS && ((!mAllowAlarms && isAlarmsStream(mStreamType)) - || (!mAllowMediaSystem && isMediaOrSystemStream(mStreamType)) + || (!mAllowMedia && isMediaStream(mStreamType)) || (!mAllowRinger && isNotificationOrRing(mStreamType)))); } @@ -454,8 +454,8 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba mNotificationPolicy = mNotificationManager.getNotificationPolicy(); mAllowAlarms = (mNotificationPolicy.priorityCategories & NotificationManager.Policy .PRIORITY_CATEGORY_ALARMS) != 0; - mAllowMediaSystem = (mNotificationPolicy.priorityCategories - & NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER) != 0; + mAllowMedia = (mNotificationPolicy.priorityCategories + & NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA) != 0; mAllowRinger = !ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted( mNotificationPolicy); updateSlider(); diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 3c3c762961870..0e96c16fc5947 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -3132,7 +3132,7 @@ public final class Settings { public static final String ALWAYS_FINISH_ACTIVITIES = Global.ALWAYS_FINISH_ACTIVITIES; /** - * Determines which streams are affected by ringer mode changes. The + * Determines which streams are affected by ringer and zen mode changes. The * stream type's bit should be set to 1 if it should be muted when going * into an inaudible ringer mode. */ diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java index 171d4d938beb3..b61919eba2507 100644 --- a/core/java/android/service/notification/ZenModeConfig.java +++ b/core/java/android/service/notification/ZenModeConfig.java @@ -85,7 +85,8 @@ public class ZenModeConfig implements Parcelable { // 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_MEDIA = true; + private static final boolean DEFAULT_ALLOW_SYSTEM = false; private static final boolean DEFAULT_ALLOW_CALLS = false; private static final boolean DEFAULT_ALLOW_MESSAGES = false; private static final boolean DEFAULT_ALLOW_REMINDERS = false; @@ -94,13 +95,14 @@ public class ZenModeConfig implements Parcelable { private static final boolean DEFAULT_ALLOW_SCREEN_OFF = true; private static final boolean DEFAULT_ALLOW_SCREEN_ON = true; - public static final int XML_VERSION = 3; + public static final int XML_VERSION = 4; public static final String ZEN_TAG = "zen"; 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_SYSTEM_OTHER = "media_system_other"; + private static final String ALLOW_ATT_MEDIA = "media"; + private static final String ALLOW_ATT_SYSTEM = "system"; 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"; @@ -134,7 +136,8 @@ public class ZenModeConfig implements Parcelable { private static final String RULE_ATT_ENABLER = "enabler"; public boolean allowAlarms = DEFAULT_ALLOW_ALARMS; - public boolean allowMediaSystemOther = DEFAULT_ALLOW_MEDIA_SYSTEM_OTHER; + public boolean allowMedia = DEFAULT_ALLOW_MEDIA; + public boolean allowSystem = DEFAULT_ALLOW_SYSTEM; public boolean allowCalls = DEFAULT_ALLOW_CALLS; public boolean allowRepeatCallers = DEFAULT_ALLOW_REPEAT_CALLERS; public boolean allowMessages = DEFAULT_ALLOW_MESSAGES; @@ -175,7 +178,8 @@ public class ZenModeConfig implements Parcelable { allowWhenScreenOff = source.readInt() == 1; allowWhenScreenOn = source.readInt() == 1; allowAlarms = source.readInt() == 1; - allowMediaSystemOther = source.readInt() == 1; + allowMedia = source.readInt() == 1; + allowSystem = source.readInt() == 1; } @Override @@ -206,7 +210,8 @@ 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); + dest.writeInt(allowMedia ? 1 : 0); + dest.writeInt(allowSystem ? 1 : 0); } @Override @@ -214,7 +219,8 @@ public class ZenModeConfig implements Parcelable { return new StringBuilder(ZenModeConfig.class.getSimpleName()).append('[') .append("user=").append(user) .append(",allowAlarms=").append(allowAlarms) - .append(",allowMediaSystemOther=").append(allowMediaSystemOther) + .append(",allowMedia=").append(allowMedia) + .append(",allowSystem=").append(allowSystem) .append(",allowReminders=").append(allowReminders) .append(",allowEvents=").append(allowEvents) .append(",allowCalls=").append(allowCalls) @@ -240,8 +246,11 @@ public class ZenModeConfig implements Parcelable { if (allowAlarms != to.allowAlarms) { d.addLine("allowAlarms", allowAlarms, to.allowAlarms); } - if (allowMediaSystemOther != to.allowMediaSystemOther) { - d.addLine("allowMediaSystemOther", allowMediaSystemOther, to.allowMediaSystemOther); + if (allowMedia != to.allowMedia) { + d.addLine("allowMedia", allowMedia, to.allowMedia); + } + if (allowSystem != to.allowSystem) { + d.addLine("allowSystem", allowSystem, to.allowSystem); } if (allowCalls != to.allowCalls) { d.addLine("allowCalls", allowCalls, to.allowCalls); @@ -361,7 +370,8 @@ public class ZenModeConfig implements Parcelable { if (o == this) return true; final ZenModeConfig other = (ZenModeConfig) o; return other.allowAlarms == allowAlarms - && other.allowMediaSystemOther == allowMediaSystemOther + && other.allowMedia == allowMedia + && other.allowSystem == allowSystem && other.allowCalls == allowCalls && other.allowRepeatCallers == allowRepeatCallers && other.allowMessages == allowMessages @@ -378,7 +388,7 @@ public class ZenModeConfig implements Parcelable { @Override public int hashCode() { - return Objects.hash(allowAlarms, allowMediaSystemOther, allowCalls, + return Objects.hash(allowAlarms, allowMedia, allowSystem, allowCalls, allowRepeatCallers, allowMessages, allowCallsFrom, allowMessagesFrom, allowReminders, allowEvents, allowWhenScreenOff, allowWhenScreenOn, user, automaticRules, manualRule); @@ -469,8 +479,9 @@ public class ZenModeConfig implements Parcelable { 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_SYSTEM_OTHER, - DEFAULT_ALLOW_MEDIA_SYSTEM_OTHER); + rt.allowMedia = safeBoolean(parser, ALLOW_ATT_MEDIA, + DEFAULT_ALLOW_MEDIA); + rt.allowSystem = safeBoolean(parser, ALLOW_ATT_SYSTEM, DEFAULT_ALLOW_SYSTEM); } else if (MANUAL_TAG.equals(tag)) { rt.manualRule = readRuleXml(parser); } else if (AUTOMATIC_TAG.equals(tag)) { @@ -502,7 +513,8 @@ public class ZenModeConfig implements Parcelable { 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_MEDIA_SYSTEM_OTHER, Boolean.toString(allowMediaSystemOther)); + out.attribute(null, ALLOW_ATT_MEDIA, Boolean.toString(allowMedia)); + out.attribute(null, ALLOW_ATT_SYSTEM, Boolean.toString(allowSystem)); out.endTag(null, ALLOW_TAG); if (manualRule != null) { @@ -699,8 +711,11 @@ public class ZenModeConfig implements Parcelable { if (allowAlarms) { priorityCategories |= Policy.PRIORITY_CATEGORY_ALARMS; } - if (allowMediaSystemOther) { - priorityCategories |= Policy.PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER; + if (allowMedia) { + priorityCategories |= Policy.PRIORITY_CATEGORY_MEDIA; + } + if (allowSystem) { + priorityCategories |= Policy.PRIORITY_CATEGORY_SYSTEM; } priorityCallSenders = sourceToPrioritySenders(allowCallsFrom, priorityCallSenders); priorityMessageSenders = sourceToPrioritySenders(allowMessagesFrom, priorityMessageSenders); @@ -743,8 +758,8 @@ public class ZenModeConfig implements Parcelable { public void applyNotificationPolicy(Policy policy) { if (policy == null) return; allowAlarms = (policy.priorityCategories & Policy.PRIORITY_CATEGORY_ALARMS) != 0; - allowMediaSystemOther = (policy.priorityCategories - & Policy.PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER) != 0; + allowMedia = (policy.priorityCategories & Policy.PRIORITY_CATEGORY_MEDIA) != 0; + allowSystem = (policy.priorityCategories & Policy.PRIORITY_CATEGORY_SYSTEM) != 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; @@ -1415,7 +1430,8 @@ public class ZenModeConfig implements Parcelable { } /** - * Determines whether dnd behavior should mute all notification sounds + * Determines whether dnd behavior should mute all notification/ringer sounds + * (sounds associated with ringer volume discluding system) */ public static boolean areAllPriorityOnlyNotificationZenSoundsMuted(NotificationManager.Policy policy) { @@ -1434,7 +1450,7 @@ public class ZenModeConfig implements Parcelable { } /** - * Determines whether dnd behavior should mute all notification sounds + * Determines whether dnd behavior should mute all sounds controlled by ringer */ public static boolean areAllPriorityOnlyNotificationZenSoundsMuted(ZenModeConfig config) { return !config.allowReminders && !config.allowCalls && !config.allowMessages @@ -1445,7 +1461,7 @@ public class ZenModeConfig implements Parcelable { * Determines whether all dnd mutes all sounds */ public static boolean areAllZenBehaviorSoundsMuted(ZenModeConfig config) { - return !config.allowAlarms && !config.allowMediaSystemOther + return !config.allowAlarms && !config.allowMedia && !config.allowSystem && areAllPriorityOnlyNotificationZenSoundsMuted(config); } diff --git a/core/res/res/xml/default_zen_mode_config.xml b/core/res/res/xml/default_zen_mode_config.xml index 7849a2ace6387..5e463d866b4df 100644 --- a/core/res/res/xml/default_zen_mode_config.xml +++ b/core/res/res/xml/default_zen_mode_config.xml @@ -18,7 +18,7 @@ --> - - + diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java index 44a2ff9e8bf72..d432658373bcd 100644 --- a/media/java/android/media/AudioAttributes.java +++ b/media/java/android/media/AudioAttributes.java @@ -19,7 +19,6 @@ package android.media; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.SystemApi; -import android.media.AudioAttributesProto; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; @@ -206,19 +205,26 @@ public final class AudioAttributes implements Parcelable { /** * @hide * Denotes a usage for alarms, - * will be muted when the Zen mode doesn't allow alarms + * will be muted when the Zen mode priority doesn't allow alarms or in Alarms Only Mode * @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. + * Denotes a usage for media, game, assistant, and navigation + * will be muted when the Zen priority mode doesn't allow media * @see #SUPPRESSIBLE_USAGES */ - public final static int SUPPRESSIBLE_MEDIA_SYSTEM_OTHER = 5; + public final static int SUPPRESSIBLE_MEDIA = 5; + /** + * @hide + * Denotes a usage for all other sounds not caught in SUPPRESSIBLE_NOTIFICATION, + * SUPPRESSIBLE_CALL,SUPPRESSIBLE_NEVER, SUPPRESSIBLE_ALARM or SUPPRESSIBLE_MEDIA. + * This includes system, sonification and unknown sounds. + * These will be muted when the Zen priority mode doesn't allow sytem sounds + * @see #SUPPRESSIBLE_USAGES + */ + public final static int SUPPRESSIBLE_SYSTEM = 6; /** * @hide @@ -239,13 +245,13 @@ public final class AudioAttributes implements Parcelable { 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); - SUPPRESSIBLE_USAGES.put(USAGE_UNKNOWN, SUPPRESSIBLE_MEDIA_SYSTEM_OTHER); + SUPPRESSIBLE_USAGES.put(USAGE_MEDIA, SUPPRESSIBLE_MEDIA); + SUPPRESSIBLE_USAGES.put(USAGE_ASSISTANCE_NAVIGATION_GUIDANCE, SUPPRESSIBLE_MEDIA); + SUPPRESSIBLE_USAGES.put(USAGE_GAME, SUPPRESSIBLE_MEDIA); + SUPPRESSIBLE_USAGES.put(USAGE_ASSISTANT, SUPPRESSIBLE_MEDIA); + SUPPRESSIBLE_USAGES.put(USAGE_VOICE_COMMUNICATION_SIGNALLING, SUPPRESSIBLE_SYSTEM); + SUPPRESSIBLE_USAGES.put(USAGE_ASSISTANCE_SONIFICATION, SUPPRESSIBLE_SYSTEM); + SUPPRESSIBLE_USAGES.put(USAGE_UNKNOWN, SUPPRESSIBLE_SYSTEM); } /** diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index 5b627ec2ed56e..1536bb6880735 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -16,7 +16,6 @@ package android.media; -import android.annotation.CallbackExecutor; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; @@ -2099,27 +2098,7 @@ public class AudioManager { */ private boolean querySoundEffectsEnabled(int user) { return Settings.System.getIntForUser(getContext().getContentResolver(), - Settings.System.SOUND_EFFECTS_ENABLED, 0, user) != 0 - && !areSystemSoundsZenModeBlocked(getContext()); - } - - private boolean areSystemSoundsZenModeBlocked(Context context) { - int zenMode = Settings.Global.getInt(context.getContentResolver(), - Settings.Global.ZEN_MODE, 0); - - switch (zenMode) { - case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS: - case Settings.Global.ZEN_MODE_ALARMS: - return true; - case Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS: - final NotificationManager noMan = (NotificationManager) context - .getSystemService(Context.NOTIFICATION_SERVICE); - return (noMan.getNotificationPolicy().priorityCategories - & NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER) == 0; - case Settings.Global.ZEN_MODE_OFF: - default: - return false; - } + Settings.System.SOUND_EFFECTS_ENABLED, 0, user) != 0; } /** diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialogController.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialogController.java index 6c31b2af039ec..c8bcdaac1d4ad 100644 --- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialogController.java +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialogController.java @@ -101,6 +101,7 @@ public interface VolumeDialogController { public int activeStream = NO_ACTIVE_STREAM; public boolean disallowAlarms; public boolean disallowMedia; + public boolean disallowSystem; public boolean disallowRinger; public State copy() { @@ -118,6 +119,7 @@ public interface VolumeDialogController { rt.activeStream = activeStream; rt.disallowAlarms = disallowAlarms; rt.disallowMedia = disallowMedia; + rt.disallowSystem = disallowSystem; rt.disallowRinger = disallowRinger; return rt; } @@ -150,6 +152,7 @@ public interface VolumeDialogController { sep(sb, indent); sb.append("activeStream:").append(activeStream); sep(sb, indent); sb.append("disallowAlarms:").append(disallowAlarms); sep(sb, indent); sb.append("disallowMedia:").append(disallowMedia); + sep(sb, indent); sb.append("disallowSystem:").append(disallowSystem); sep(sb, indent); sb.append("disallowRinger:").append(disallowRinger); if (indent > 0) sep(sb, indent); return sb.append('}').toString(); diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index eedc50f23d600..694026473dc0c 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -1697,8 +1697,6 @@ public class KeyguardViewMediator extends SystemUI { mUiOffloadThread.submit(() -> { // If the stream is muted, don't play the sound if (mAudioManager.isStreamMute(mUiSoundsStreamType)) return; - // If DND blocks the sound, don't play the sound - if (areSystemSoundsZenModeBlocked(mContext)) return; int id = mLockSounds.play(soundId, mLockSoundVolume, mLockSoundVolume, 1/*priortiy*/, 0/*loop*/, 1.0f/*rate*/); @@ -1710,25 +1708,6 @@ public class KeyguardViewMediator extends SystemUI { } } - private boolean areSystemSoundsZenModeBlocked(Context context) { - int zenMode = Settings.Global.getInt(context.getContentResolver(), - Settings.Global.ZEN_MODE, 0); - - switch (zenMode) { - case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS: - case Settings.Global.ZEN_MODE_ALARMS: - return true; - case Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS: - final NotificationManager noMan = (NotificationManager) context - .getSystemService(Context.NOTIFICATION_SERVICE); - return (noMan.getNotificationPolicy().priorityCategories - & NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER) == 0; - case Settings.Global.ZEN_MODE_OFF: - default: - return false; - } - } - private void playTrustedSound() { playSound(mTrustedSoundId); } diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java index 7c71b2a058f59..89e7dd1460457 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java @@ -521,18 +521,23 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa boolean disallowAlarms = (policy.priorityCategories & NotificationManager.Policy .PRIORITY_CATEGORY_ALARMS) == 0; boolean disallowMedia = (policy.priorityCategories & NotificationManager.Policy - .PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER) == 0; + .PRIORITY_CATEGORY_MEDIA) == 0; + boolean disallowSystem = (policy.priorityCategories & NotificationManager.Policy + .PRIORITY_CATEGORY_SYSTEM) == 0; boolean disallowRinger = ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(policy); - if (mState.disallowAlarms == disallowAlarms && mState.disallowMedia == disallowMedia - && mState.disallowRinger == disallowRinger) { + if (mState.disallowAlarms == disallowAlarms + && mState.disallowMedia == disallowMedia + && mState.disallowRinger == disallowRinger + && mState.disallowSystem == disallowSystem) { return false; } mState.disallowAlarms = disallowAlarms; mState.disallowMedia = disallowMedia; + mState.disallowSystem = disallowSystem; mState.disallowRinger = disallowRinger; Events.writeEvent(mContext, Events.EVENT_ZEN_CONFIG_CHANGED, "disallowAlarms=" + - disallowAlarms + " disallowMedia=" + disallowMedia + " disallowRinger=" + - disallowRinger); + disallowAlarms + " disallowMedia=" + disallowMedia + " disallowSystem=" + + disallowSystem + " disallowRinger=" + disallowRinger); return true; } diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java index 90a9fc877fea5..716b588412b51 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java @@ -691,7 +691,8 @@ public class VolumeDialogImpl implements VolumeDialog { : isZenNone ? (isRingStream || isSystemStream || isAlarmStream || isMusicStream) : isZenPriorityOnly ? ((isAlarmStream && mState.disallowAlarms) || (isMusicStream && mState.disallowMedia) || - (isRingStream && mState.disallowRinger)) + (isRingStream && mState.disallowRinger) || + (isSystemStream && mState.disallowSystem)) : false; // update slider max diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 8eb8058ab8062..3b5cad660d2cb 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -20,6 +20,9 @@ import static android.Manifest.permission.REMOTE_AUDIO_PLAYBACK; import static android.media.AudioManager.RINGER_MODE_NORMAL; import static android.media.AudioManager.RINGER_MODE_SILENT; import static android.media.AudioManager.RINGER_MODE_VIBRATE; +import static android.media.AudioManager.STREAM_ALARM; +import static android.media.AudioManager.STREAM_MUSIC; +import static android.media.AudioManager.STREAM_SYSTEM; import static android.os.Process.FIRST_APPLICATION_UID; import android.Manifest; @@ -414,8 +417,10 @@ public class AudioService extends IAudioService.Stub /** @see System#MODE_RINGER_STREAMS_AFFECTED */ private int mRingerModeAffectedStreams = 0; - // Streams currently muted by ringer mode - private int mRingerModeMutedStreams; + private int mZenModeAffectedStreams = 0; + + // Streams currently muted by ringer mode and dnd + private int mRingerAndZenModeMutedStreams; /** Streams that can be muted. Do not resolve to aliases when checking. * @see System#MUTE_STREAMS_AFFECTED */ @@ -767,7 +772,7 @@ public class AudioService extends IAudioService.Stub // Call setRingerModeInt() to apply correct mute // state on streams affected by ringer mode. - mRingerModeMutedStreams = 0; + mRingerAndZenModeMutedStreams = 0; setRingerModeInt(getRingerModeInternal(), false); // Register for device connection intent broadcasts. @@ -1278,7 +1283,7 @@ public class AudioService extends IAudioService.Stub mHasVibrator ? AudioManager.VIBRATE_SETTING_ONLY_SILENT : AudioManager.VIBRATE_SETTING_OFF); - updateRingerModeAffectedStreams(); + updateRingerAndZenModeAffectedStreams(); readDockAudioSettings(cr); sendEncodedSurroundMode(cr, "readPersistedSettings"); } @@ -1529,7 +1534,9 @@ public class AudioService extends IAudioService.Stub flags |= AudioManager.FLAG_SHOW_VIBRATE_HINT; } } - // If the ringermode is suppressing media, prevent changes + + // If the ringer mode or zen is muting the stream, do not change stream unless + // it'll cause us to exit dnd if (!volumeAdjustmentAllowedByDnd(streamTypeAlias, flags)) { adjustVolume = false; } @@ -1876,18 +1883,19 @@ public class AudioService extends IAudioService.Stub sendVolumeUpdate(streamType, oldIndex, index, flags); } - // No ringer affected streams can be changed in total silence mode or priority-only - // (with alarms/media toggled off) except those that will cause the device to exit - // the mode. + // No ringer or zen muted stream volumes can be changed unless it'll exit dnd private boolean volumeAdjustmentAllowedByDnd(int streamTypeAlias, int flags) { - if ((mNm.getZenMode() == Settings.Global.ZEN_MODE_NO_INTERRUPTIONS - || mNm.getZenMode() == Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) - && isStreamMutedByRingerMode(streamTypeAlias)) { - if (!(((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) || - (streamTypeAlias == getUiSoundsStreamType()))) { - return false; - } + switch (mNm.getZenMode()) { + case Settings.Global.ZEN_MODE_OFF: + return true; + case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS: + case Settings.Global.ZEN_MODE_ALARMS: + case Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS: + return !isStreamMutedByRingerOrZenMode(streamTypeAlias) + || streamTypeAlias == getUiSoundsStreamType() + || (flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0; } + return true; } @@ -2403,9 +2411,9 @@ public class AudioService extends IAudioService.Stub } private void muteRingerModeStreams() { - // Mute stream if not previously muted by ringer mode and ringer mode - // is not RINGER_MODE_NORMAL and stream is affected by ringer mode. - // Unmute stream if previously muted by ringer mode and ringer mode + // Mute stream if not previously muted by ringer mode and (ringer mode + // is not RINGER_MODE_NORMAL OR stream is zen muted) and stream is affected by ringer mode. + // Unmute stream if previously muted by ringer/zen mode and ringer mode // is RINGER_MODE_NORMAL or stream is not affected by ringer mode. int numStreamTypes = AudioSystem.getNumStreamTypes(); @@ -2413,25 +2421,14 @@ public class AudioService extends IAudioService.Stub mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); } - // in priority only dnd, alarms and media streams can be muted when ringer is not muted - boolean isZenPriorityMode = mNm.getZenMode() == - Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; - NotificationManager.Policy zenPolicy = mNm.getNotificationPolicy(); - boolean muteAlarms = isZenPriorityMode && ((zenPolicy.priorityCategories - & NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS) == 0); - boolean muteMedia = isZenPriorityMode && ((zenPolicy.priorityCategories - & NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER) == 0); - final boolean ringerModeMute = mRingerMode == AudioManager.RINGER_MODE_VIBRATE || mRingerMode == AudioManager.RINGER_MODE_SILENT; for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { - final boolean isMuted = isStreamMutedByRingerMode(streamType); - - final boolean shouldZenMute = (isAlarm(streamType) && muteAlarms) - || (isMedia(streamType) && muteMedia); - final boolean shouldMute = (shouldZenMute || ringerModeMute) - && isStreamAffectedByRingerMode(streamType); + final boolean isMuted = isStreamMutedByRingerOrZenMode(streamType); + final boolean shouldZenMute = shouldZenMuteStream(streamType); + final boolean shouldMute = shouldZenMute || (ringerModeMute + && isStreamAffectedByRingerMode(streamType)); if (isMuted == shouldMute) continue; if (!shouldMute) { // unmute @@ -2458,11 +2455,11 @@ public class AudioService extends IAudioService.Stub } } mStreamStates[streamType].mute(false); - mRingerModeMutedStreams &= ~(1 << streamType); + mRingerAndZenModeMutedStreams &= ~(1 << streamType); } else { // mute mStreamStates[streamType].mute(true); - mRingerModeMutedStreams |= (1 << streamType); + mRingerAndZenModeMutedStreams |= (1 << streamType); } } } @@ -2477,7 +2474,12 @@ public class AudioService extends IAudioService.Stub } private boolean isMedia(int streamType) { - return streamType == AudioSystem.STREAM_SYSTEM || streamType == AudioSystem.STREAM_MUSIC; + return streamType == AudioSystem.STREAM_MUSIC; + } + + + private boolean isSystem(int streamType) { + return streamType == AudioSystem.STREAM_SYSTEM; } private void setRingerModeInt(int ringerMode, boolean persist) { @@ -2836,6 +2838,11 @@ public class AudioService extends IAudioService.Stub /** @see AudioManager#playSoundEffect(int, float) */ public void playSoundEffectVolume(int effectType, float volume) { + // do not try to play the sound effect if the system stream is muted + if (isStreamMutedByRingerOrZenMode(STREAM_SYSTEM)) { + return; + } + if (effectType >= AudioManager.NUM_SOUND_EFFECTS || effectType < 0) { Log.w(TAG, "AudioService effectType value " + effectType + " out of range"); return; @@ -2953,7 +2960,7 @@ public class AudioService extends IAudioService.Stub synchronized (VolumeStreamState.class) { // unmute stream that was muted but is not affect by mute anymore if (streamState.mIsMuted && ((!isStreamAffectedByMute(streamType) && - !isStreamMutedByRingerMode(streamType)) || mUseFixedVolume)) { + !isStreamMutedByRingerOrZenMode(streamType)) || mUseFixedVolume)) { streamState.mIsMuted = false; } } @@ -3899,12 +3906,69 @@ public class AudioService extends IAudioService.Stub return (mRingerModeAffectedStreams & (1 << streamType)) != 0; } - private boolean isStreamMutedByRingerMode(int streamType) { - return (mRingerModeMutedStreams & (1 << streamType)) != 0; + private boolean shouldZenMuteStream(int streamType) { + if (mNm.getZenMode() != Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) { + return false; + } + + NotificationManager.Policy zenPolicy = mNm.getNotificationPolicy(); + final boolean muteAlarms = (zenPolicy.priorityCategories + & NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS) == 0; + final boolean muteMedia = (zenPolicy.priorityCategories + & NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA) == 0; + final boolean muteSystem = (zenPolicy.priorityCategories + & NotificationManager.Policy.PRIORITY_CATEGORY_SYSTEM) == 0; + final boolean muteNotificationAndRing = ZenModeConfig + .areAllPriorityOnlyNotificationZenSoundsMuted(mNm.getNotificationPolicy()); + return muteAlarms && isAlarm(streamType) + || muteMedia && isMedia(streamType) + || muteSystem && isSystem(streamType) + || muteNotificationAndRing && isNotificationOrRinger(streamType); + } + + private boolean isStreamMutedByRingerOrZenMode(int streamType) { + return (mRingerAndZenModeMutedStreams & (1 << streamType)) != 0; + } + + /** + * DND total silence: media and alarms streams are tied to the muted ringer + * {@link ZenModeHelper.RingerModeDelegate#getRingerModeAffectedStreams(int)} + * DND alarms only: notification, ringer + system muted (by default tied to muted ringer mode) + * DND priority only: alarms, media, system streams can be muted separate from ringer based on + * zenPolicy (this method determines which streams) + * @return true if changed, else false + */ + private boolean updateZenModeAffectedStreams() { + int zenModeAffectedStreams = 0; + if (mSystemReady && mNm.getZenMode() == Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) { + NotificationManager.Policy zenPolicy = mNm.getNotificationPolicy(); + if ((zenPolicy.priorityCategories + & NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS) == 0) { + zenModeAffectedStreams |= 1 << AudioManager.STREAM_ALARM; + } + + if ((zenPolicy.priorityCategories + & NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA) == 0) { + zenModeAffectedStreams |= 1 << AudioManager.STREAM_MUSIC; + } + + if ((zenPolicy.priorityCategories + & NotificationManager.Policy.PRIORITY_CATEGORY_SYSTEM) == 0) { + zenModeAffectedStreams |= 1 << AudioManager.STREAM_SYSTEM; + } + } + + if (mZenModeAffectedStreams != zenModeAffectedStreams) { + mZenModeAffectedStreams = zenModeAffectedStreams; + return true; + } + + return false; } @GuardedBy("mSettingsLock") - private boolean updateRingerModeAffectedStreams() { + private boolean updateRingerAndZenModeAffectedStreams() { + boolean updatedZenModeAffectedStreams = updateZenModeAffectedStreams(); int ringerModeAffectedStreams = Settings.System.getIntForUser(mContentResolver, Settings.System.MODE_RINGER_STREAMS_AFFECTED, ((1 << AudioSystem.STREAM_RING)|(1 << AudioSystem.STREAM_NOTIFICATION)| @@ -3936,7 +4000,7 @@ public class AudioService extends IAudioService.Stub mRingerModeAffectedStreams = ringerModeAffectedStreams; return true; } - return false; + return updatedZenModeAffectedStreams; } @Override @@ -5259,6 +5323,10 @@ public class AudioService extends IAudioService.Stub SettingsObserver() { super(new Handler()); + mContentResolver.registerContentObserver(Settings.Global.getUriFor( + Settings.Global.ZEN_MODE), false, this); + mContentResolver.registerContentObserver(Settings.Global.getUriFor( + Settings.Global.ZEN_MODE_CONFIG_ETAG), false, this); mContentResolver.registerContentObserver(Settings.System.getUriFor( Settings.System.MODE_RINGER_STREAMS_AFFECTED), false, this); mContentResolver.registerContentObserver(Settings.Global.getUriFor( @@ -5277,11 +5345,11 @@ public class AudioService extends IAudioService.Stub public void onChange(boolean selfChange) { super.onChange(selfChange); // FIXME This synchronized is not necessary if mSettingsLock only protects mRingerMode. - // However there appear to be some missing locks around mRingerModeMutedStreams + // However there appear to be some missing locks around mRingerAndZenModeMutedStreams // and mRingerModeAffectedStreams, so will leave this synchronized for now. - // mRingerModeMutedStreams and mMuteAffectedStreams are safe (only accessed once). + // mRingerAndZenModeMutedStreams and mMuteAffectedStreams are safe (only accessed once). synchronized (mSettingsLock) { - if (updateRingerModeAffectedStreams()) { + if (updateRingerAndZenModeAffectedStreams()) { /* * Ensure all stream types that should be affected by ringer mode * are in the proper state. @@ -6614,7 +6682,7 @@ public class AudioService extends IAudioService.Stub pw.println("- mode (internal) = " + RINGER_MODE_NAMES[mRingerMode]); pw.println("- mode (external) = " + RINGER_MODE_NAMES[mRingerModeExternal]); dumpRingerModeStreams(pw, "affected", mRingerModeAffectedStreams); - dumpRingerModeStreams(pw, "muted", mRingerModeMutedStreams); + dumpRingerModeStreams(pw, "muted", mRingerAndZenModeMutedStreams); pw.print("- delegate = "); pw.println(mRingerModeDelegate); } @@ -6911,7 +6979,7 @@ public class AudioService extends IAudioService.Stub mRingerModeDelegate = delegate; if (mRingerModeDelegate != null) { synchronized (mSettingsLock) { - updateRingerModeAffectedStreams(); + updateRingerAndZenModeAffectedStreams(); } setRingerModeInternal(getRingerModeInternal(), TAG + ".setRingerModeDelegate"); } @@ -6952,7 +7020,7 @@ public class AudioService extends IAudioService.Stub @Override public void updateRingerModeAffectedStreamsInternal() { synchronized (mSettingsLock) { - if (updateRingerModeAffectedStreams()) { + if (updateRingerAndZenModeAffectedStreams()) { setRingerModeInt(getRingerModeInternal(), false); } } diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index efc948bbcf1af..cd387b017c53e 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -124,7 +124,6 @@ import android.os.IDeviceIdleController; import android.os.IInterface; import android.os.Looper; import android.os.Message; -import android.os.Parcelable; import android.os.Process; import android.os.RemoteException; import android.os.ResultReceiver; @@ -3053,8 +3052,9 @@ public class NotificationManagerService extends SystemService { /** * Sets the notification policy. Apps that target API levels below * {@link android.os.Build.VERSION_CODES#P} cannot change user-designated values to - * allow or disallow {@link Policy#PRIORITY_CATEGORY_ALARMS} and - * {@link Policy#PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER} from bypassing dnd + * allow or disallow {@link Policy#PRIORITY_CATEGORY_ALARMS}, + * {@link Policy#PRIORITY_CATEGORY_SYSTEM} and + * {@link Policy#PRIORITY_CATEGORY_MEDIA} from bypassing dnd */ @Override public void setNotificationPolicy(String pkg, Policy policy) { @@ -3070,16 +3070,25 @@ public class NotificationManagerService extends SystemService { int priorityCategories = policy.priorityCategories; // ignore alarm and media values from new policy priorityCategories &= ~Policy.PRIORITY_CATEGORY_ALARMS; - priorityCategories &= ~Policy.PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER; + priorityCategories &= ~Policy.PRIORITY_CATEGORY_MEDIA; + priorityCategories &= ~Policy.PRIORITY_CATEGORY_SYSTEM; // use user-designated values - priorityCategories |= currPolicy.PRIORITY_CATEGORY_ALARMS; - priorityCategories |= currPolicy.PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER; + priorityCategories |= currPolicy.priorityCategories + & Policy.PRIORITY_CATEGORY_ALARMS; + priorityCategories |= currPolicy.priorityCategories + & Policy.PRIORITY_CATEGORY_MEDIA; + priorityCategories |= currPolicy.priorityCategories + & Policy.PRIORITY_CATEGORY_SYSTEM; policy = new Policy(priorityCategories, policy.priorityCallSenders, policy.priorityMessageSenders, policy.suppressedVisualEffects); } + Slog.i(TAG, "setNotificationPolicy pkg=" + pkg + + " targetSdk=" + applicationInfo.targetSdkVersion + + " policy=" + + Policy.priorityCategoriesToString(policy.priorityCategories)); mZenModeHelper.setNotificationPolicy(policy); } catch (RemoteException e) { } finally { diff --git a/services/core/java/com/android/server/notification/ZenModeFiltering.java b/services/core/java/com/android/server/notification/ZenModeFiltering.java index abf2900654fd8..a0003a56e537a 100644 --- a/services/core/java/com/android/server/notification/ZenModeFiltering.java +++ b/services/core/java/com/android/server/notification/ZenModeFiltering.java @@ -163,11 +163,16 @@ 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"); + if (isMedia(record)) { + if (!config.allowMedia) { + ZenLog.traceIntercepted(record, "!allowMedia"); + return true; + } + return false; + } + if (isSystem(record)) { + if (!config.allowSystem) { + ZenLog.traceIntercepted(record, "!allowSystem"); return true; } return false; @@ -206,6 +211,18 @@ public class ZenModeFiltering { || record.isCategory(Notification.CATEGORY_CALL)); } + public boolean isMedia(NotificationRecord record) { + AudioAttributes aa = record.getAudioAttributes(); + return aa != null && AudioAttributes.SUPPRESSIBLE_USAGES.get(aa.getUsage()) == + AudioAttributes.SUPPRESSIBLE_MEDIA; + } + + public boolean isSystem(NotificationRecord record) { + AudioAttributes aa = record.getAudioAttributes(); + return aa != null && AudioAttributes.SUPPRESSIBLE_USAGES.get(aa.getUsage()) == + AudioAttributes.SUPPRESSIBLE_SYSTEM; + } + private boolean isDefaultPhoneApp(String pkg) { if (mDefaultPhoneApp == null) { final TelecomManager telecomm = diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java index 1a196982dc802..6ab7748ff116b 100644 --- a/services/core/java/com/android/server/notification/ZenModeHelper.java +++ b/services/core/java/com/android/server/notification/ZenModeHelper.java @@ -98,7 +98,8 @@ public class ZenModeHelper { protected ZenModeConfig mDefaultConfig; private final ArrayList mCallbacks = new ArrayList(); private final ZenModeFiltering mFiltering; - private final RingerModeDelegate mRingerModeDelegate = new RingerModeDelegate(); + protected final RingerModeDelegate mRingerModeDelegate = new + RingerModeDelegate(); private final ZenModeConditions mConditions; private final SparseArray mConfigs = new SparseArray<>(); private final Metrics mMetrics = new Metrics(); @@ -601,9 +602,9 @@ public class ZenModeHelper { pw.println(config); return; } - pw.printf("allow(alarms=%b,media=%bcalls=%b,callsFrom=%s,repeatCallers=%b,messages=%b,messagesFrom=%s," + pw.printf("allow(alarms=%b,media=%b,system=%b,calls=%b,callsFrom=%s,repeatCallers=%b,messages=%b,messagesFrom=%s," + "events=%b,reminders=%b,whenScreenOff=%b,whenScreenOn=%b)\n", - config.allowAlarms, config.allowMediaSystemOther, + config.allowAlarms, config.allowMedia, config.allowSystem, config.allowCalls, ZenModeConfig.sourceToString(config.allowCallsFrom), config.allowRepeatCallers, config.allowMessages, ZenModeConfig.sourceToString(config.allowMessagesFrom), @@ -781,6 +782,7 @@ public class ZenModeHelper { } private void setPreviousRingerModeSetting(Integer previousRingerLevel) { + Slog.d("beverlyt", "setPreviousRingerMode=" + previousRingerLevel); Global.putString( mContext.getContentResolver(), Global.ZEN_MODE_RINGER_LEVEL, previousRingerLevel == null ? null : Integer.toString(previousRingerLevel)); @@ -792,8 +794,8 @@ public class ZenModeHelper { final int zen = computeZenMode(); ZenLog.traceSetZenMode(zen, reason); mZenMode = zen; - updateRingerModeAffectedStreams(); setZenModeSetting(mZenMode); + updateRingerModeAffectedStreams(); if (setRingerMode) { applyZenToRingerMode(); } @@ -849,8 +851,10 @@ public class ZenModeHelper { || (mSuppressedEffects & SUPPRESSED_EFFECT_CALLS) != 0; // alarm restrictions final boolean muteAlarms = zenPriorityOnly && !mConfig.allowAlarms; - // alarm restrictions - final boolean muteMediaAndSystemSounds = zenPriorityOnly && !mConfig.allowMediaSystemOther; + // media restrictions + final boolean muteMedia = zenPriorityOnly && !mConfig.allowMedia; + // system restrictions + final boolean muteSystem = zenAlarmsOnly || (zenPriorityOnly && !mConfig.allowSystem); // total silence restrictions final boolean muteEverything = zenSilence || (zenPriorityOnly && ZenModeConfig.areAllZenBehaviorSoundsMuted(mConfig)); @@ -865,8 +869,10 @@ public class ZenModeHelper { 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 if (suppressionBehavior == AudioAttributes.SUPPRESSIBLE_MEDIA) { + applyRestrictions(muteMedia || muteEverything, usage); + } else if (suppressionBehavior == AudioAttributes.SUPPRESSIBLE_SYSTEM) { + applyRestrictions(muteSystem || muteEverything, usage); } else { applyRestrictions(muteEverything, usage); } @@ -901,7 +907,8 @@ public class ZenModeHelper { } break; case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS: - if (ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(mConfig)) { + if (ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(mConfig) + && ringerModeInternal != AudioManager.RINGER_MODE_SILENT) { setPreviousRingerModeSetting(ringerModeInternal); newRingerModeInternal = AudioManager.RINGER_MODE_SILENT; } @@ -1028,7 +1035,7 @@ public class ZenModeHelper { || mZenMode == Global.ZEN_MODE_ALARMS || (mZenMode == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS && ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted( - mConfig)))) { + mConfig)))) { newZen = Global.ZEN_MODE_OFF; } else if (mZenMode != Global.ZEN_MODE_OFF) { ringerModeExternalOut = AudioManager.RINGER_MODE_SILENT; @@ -1096,32 +1103,28 @@ public class ZenModeHelper { @Override public int getRingerModeAffectedStreams(int streams) { - // ringtone, notification and system streams are always affected by ringer mode + // ringtone and notification streams are always affected by ringer mode + // system stream is affected by ringer mode when not in priority-only streams |= (1 << AudioSystem.STREAM_RING) | - (1 << AudioSystem.STREAM_NOTIFICATION) | - (1 << AudioSystem.STREAM_SYSTEM); + (1 << AudioSystem.STREAM_NOTIFICATION) | + (1 << AudioSystem.STREAM_SYSTEM); if (mZenMode == Global.ZEN_MODE_NO_INTERRUPTIONS) { // alarm and music streams affected by ringer mode when in total silence streams |= (1 << AudioSystem.STREAM_ALARM) | - (1 << AudioSystem.STREAM_MUSIC); - } else if (mZenMode == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) { - // alarm and music streams affected by ringer mode when in priority only with - // media and alarms not allowed to bypass dnd - if (!mConfig.allowMediaSystemOther) { - streams |= (1 << AudioSystem.STREAM_MUSIC); - } else { - streams &= ~(1 << AudioSystem.STREAM_MUSIC); - } - - if (!mConfig.allowAlarms) { - streams |= (1 << AudioSystem.STREAM_ALARM); - } else { - streams &= ~(1 << AudioSystem.STREAM_ALARM); - } + (1 << AudioSystem.STREAM_MUSIC); } else { streams &= ~((1 << AudioSystem.STREAM_ALARM) | - (1 << AudioSystem.STREAM_MUSIC)); + (1 << AudioSystem.STREAM_MUSIC)); + } + + if (mZenMode == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS + && ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(mConfig)) { + // system stream is not affected by ringer mode in priority only when the ringer + // is zen muted (all other notification categories are muted) + streams &= ~(1 << AudioSystem.STREAM_SYSTEM); + } else { + streams |= (1 << AudioSystem.STREAM_SYSTEM); } return streams; } 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 6948b722049be..93c711c4cbc03 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java @@ -41,6 +41,7 @@ import android.media.AudioAttributes; import android.media.AudioManager; import android.media.AudioManagerInternal; import android.media.VolumePolicy; +import android.media.AudioSystem; import android.provider.Settings; import android.provider.Settings.Global; import android.service.notification.ZenModeConfig; @@ -50,6 +51,7 @@ import android.testing.TestableLooper; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.server.UiServiceTestCase; +import android.util.Slog; import org.junit.Before; import org.junit.Test; @@ -101,7 +103,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { public void testZenOn_AllowAlarmsMedia_NoAlarmMediaMuteApplied() { mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; assertTrue(mZenModeHelperSpy.mConfig.allowAlarms); - assertTrue(mZenModeHelperSpy.mConfig.allowMediaSystemOther); + assertTrue(mZenModeHelperSpy.mConfig.allowMedia); mZenModeHelperSpy.applyRestrictions(); verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, AudioAttributes.USAGE_ALARM); @@ -111,34 +113,32 @@ public class ZenModeHelperTest extends UiServiceTestCase { @Test public void testZenOn_DisallowAlarmsMedia_AlarmMediaMuteApplied() { - mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; mZenModeHelperSpy.mConfig.allowAlarms = false; - mZenModeHelperSpy.mConfig.allowMediaSystemOther = false; + mZenModeHelperSpy.mConfig.allowMedia = false; + mZenModeHelperSpy.mConfig.allowSystem = false; assertFalse(mZenModeHelperSpy.mConfig.allowAlarms); - assertFalse(mZenModeHelperSpy.mConfig.allowMediaSystemOther); + assertFalse(mZenModeHelperSpy.mConfig.allowMedia); + assertFalse(mZenModeHelperSpy.mConfig.allowSystem); mZenModeHelperSpy.applyRestrictions(); verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true, AudioAttributes.USAGE_ALARM); - // Media is a catch-all that includes games and system sounds + // Media is a catch-all that includes games 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); - verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true, - AudioAttributes.USAGE_UNKNOWN); } @Test public void testAlarmsOnly_alarmMediaMuteNotApplied() { mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_ALARMS; mZenModeHelperSpy.mConfig.allowAlarms = false; - mZenModeHelperSpy.mConfig.allowMediaSystemOther = false; + mZenModeHelperSpy.mConfig.allowSystem = false; + mZenModeHelperSpy.mConfig.allowMedia = false; assertFalse(mZenModeHelperSpy.mConfig.allowAlarms); - assertFalse(mZenModeHelperSpy.mConfig.allowMediaSystemOther); + assertFalse(mZenModeHelperSpy.mConfig.allowMedia); mZenModeHelperSpy.applyRestrictions(); // Alarms only mode will not silence alarms @@ -150,9 +150,11 @@ public class ZenModeHelperTest extends UiServiceTestCase { AudioAttributes.USAGE_MEDIA); verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, AudioAttributes.USAGE_GAME); - verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, + + // Alarms only will silence system noises + verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true, AudioAttributes.USAGE_ASSISTANCE_SONIFICATION); - verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, + verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true, AudioAttributes.USAGE_UNKNOWN); } @@ -175,14 +177,15 @@ public class ZenModeHelperTest extends UiServiceTestCase { // Only audio attributes with SUPPRESIBLE_NEVER can bypass mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_ALARMS; mZenModeHelperSpy.mConfig.allowAlarms = false; - mZenModeHelperSpy.mConfig.allowMediaSystemOther = false; + mZenModeHelperSpy.mConfig.allowMedia = false; + mZenModeHelperSpy.mConfig.allowSystem = false; mZenModeHelperSpy.mConfig.allowReminders = false; mZenModeHelperSpy.mConfig.allowCalls = false; mZenModeHelperSpy.mConfig.allowMessages = false; mZenModeHelperSpy.mConfig.allowEvents = false; mZenModeHelperSpy.mConfig.allowRepeatCallers= false; assertFalse(mZenModeHelperSpy.mConfig.allowAlarms); - assertFalse(mZenModeHelperSpy.mConfig.allowMediaSystemOther); + assertFalse(mZenModeHelperSpy.mConfig.allowMedia); assertFalse(mZenModeHelperSpy.mConfig.allowReminders); assertFalse(mZenModeHelperSpy.mConfig.allowCalls); assertFalse(mZenModeHelperSpy.mConfig.allowMessages); @@ -199,14 +202,15 @@ public class ZenModeHelperTest extends UiServiceTestCase { // Only audio attributes with SUPPRESIBLE_NEVER can bypass mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; mZenModeHelperSpy.mConfig.allowAlarms = false; - mZenModeHelperSpy.mConfig.allowMediaSystemOther = false; + mZenModeHelperSpy.mConfig.allowMedia = false; + mZenModeHelperSpy.mConfig.allowSystem = false; mZenModeHelperSpy.mConfig.allowReminders = false; mZenModeHelperSpy.mConfig.allowCalls = false; mZenModeHelperSpy.mConfig.allowMessages = false; mZenModeHelperSpy.mConfig.allowEvents = false; mZenModeHelperSpy.mConfig.allowRepeatCallers= false; assertFalse(mZenModeHelperSpy.mConfig.allowAlarms); - assertFalse(mZenModeHelperSpy.mConfig.allowMediaSystemOther); + assertFalse(mZenModeHelperSpy.mConfig.allowMedia); assertFalse(mZenModeHelperSpy.mConfig.allowReminders); assertFalse(mZenModeHelperSpy.mConfig.allowCalls); assertFalse(mZenModeHelperSpy.mConfig.allowMessages); @@ -278,6 +282,63 @@ public class ZenModeHelperTest extends UiServiceTestCase { mZenModeHelperSpy.TAG); } + @Test + public void testRingerAffectedStreamsTotalSilence() { + // in total silence: + // ringtone, notification, system, alarm, streams, music are affected by ringer mode + mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_NO_INTERRUPTIONS; + ZenModeHelper.RingerModeDelegate ringerModeDelegate = + mZenModeHelperSpy.new RingerModeDelegate(); + int ringerModeAffectedStreams = ringerModeDelegate.getRingerModeAffectedStreams(0); + assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_RING)) != 0); + assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_NOTIFICATION)) + != 0); + assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_SYSTEM)) != 0); + assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_ALARM)) != 0); + assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_MUSIC)) != 0); + } + + @Test + public void testRingerAffectedStreamsPriorityOnly() { + // in priority only mode: + // ringtone, notification and system streams are affected by ringer mode + // UNLESS ringer is muted due to all the other priority only dnd sounds being muted + mZenModeHelperSpy.mConfig.allowAlarms = true; + mZenModeHelperSpy.mConfig.allowReminders = true; + mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; + ZenModeHelper.RingerModeDelegate ringerModeDelegateRingerMuted = + mZenModeHelperSpy.new RingerModeDelegate(); + + int ringerModeAffectedStreams = + ringerModeDelegateRingerMuted.getRingerModeAffectedStreams(0); + assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_RING)) != 0); + assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_NOTIFICATION)) + != 0); + assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_SYSTEM)) != 0); + assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_ALARM)) == 0); + assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_MUSIC)) == 0); + + // special case: if ringer is muted (since all notification sounds cannot bypass) + // then system stream is not affected by ringer mode + mZenModeHelperSpy.mConfig.allowReminders = false; + mZenModeHelperSpy.mConfig.allowCalls = false; + mZenModeHelperSpy.mConfig.allowMessages = false; + mZenModeHelperSpy.mConfig.allowEvents = false; + mZenModeHelperSpy.mConfig.allowRepeatCallers= false; + ZenModeHelper.RingerModeDelegate ringerModeDelegateRingerNotMuted = + mZenModeHelperSpy.new RingerModeDelegate(); + + int ringerMutedRingerModeAffectedStreams = + ringerModeDelegateRingerNotMuted.getRingerModeAffectedStreams(0); + assertTrue((ringerMutedRingerModeAffectedStreams & (1 << AudioSystem.STREAM_RING)) != 0); + assertTrue((ringerMutedRingerModeAffectedStreams & (1 << AudioSystem.STREAM_NOTIFICATION)) + != 0); + assertTrue((ringerMutedRingerModeAffectedStreams & (1 << AudioSystem.STREAM_SYSTEM)) + == 0); + assertTrue((ringerMutedRingerModeAffectedStreams & (1 << AudioSystem.STREAM_ALARM)) == 0); + assertTrue((ringerMutedRingerModeAffectedStreams & (1 << AudioSystem.STREAM_MUSIC)) == 0); + } + @Test public void testZenSetInternalRinger_NotAllPriorityNotificationSoundsMuted_StartNormal() { AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);