diff --git a/core/java/android/preference/SeekBarVolumizer.java b/core/java/android/preference/SeekBarVolumizer.java index 2b3a2ab05e821..4dd9baba3e5f5 100644 --- a/core/java/android/preference/SeekBarVolumizer.java +++ b/core/java/android/preference/SeekBarVolumizer.java @@ -151,7 +151,7 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba .PRIORITY_CATEGORY_ALARMS) != 0; mAllowMedia = (mNotificationPolicy.priorityCategories & NotificationManager.Policy .PRIORITY_CATEGORY_MEDIA) != 0; - mAllowRinger = !ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted( + mAllowRinger = !ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted( mNotificationPolicy); mStreamType = streamType; mAffectedByRingerMode = mAudioManager.isStreamAffectedByRingerMode(mStreamType); @@ -571,7 +571,7 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba .PRIORITY_CATEGORY_ALARMS) != 0; mAllowMedia = (mNotificationPolicy.priorityCategories & NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA) != 0; - mAllowRinger = !ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted( + mAllowRinger = !ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted( mNotificationPolicy); updateSlider(); } diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java index 937990f7e88e0..1f2c872a22334 100644 --- a/core/java/android/service/notification/ZenModeConfig.java +++ b/core/java/android/service/notification/ZenModeConfig.java @@ -1904,10 +1904,10 @@ public class ZenModeConfig implements Parcelable { } /** - * Determines whether dnd behavior should mute all notification/ringer sounds - * (sounds associated with ringer volume discluding system) + * Determines whether dnd behavior should mute all ringer-controlled sounds + * This includes notification, ringer and system sounds */ - public static boolean areAllPriorityOnlyNotificationZenSoundsMuted(NotificationManager.Policy + public static boolean areAllPriorityOnlyRingerSoundsMuted(NotificationManager.Policy policy) { boolean allowReminders = (policy.priorityCategories & NotificationManager.Policy.PRIORITY_CATEGORY_REMINDERS) != 0; @@ -1920,20 +1920,19 @@ public class ZenModeConfig implements Parcelable { boolean allowRepeatCallers = (policy.priorityCategories & NotificationManager.Policy.PRIORITY_CATEGORY_REPEAT_CALLERS) != 0; boolean areChannelsBypassingDnd = (policy.state & Policy.STATE_CHANNELS_BYPASSING_DND) != 0; + boolean allowSystem = (policy.priorityCategories & Policy.PRIORITY_CATEGORY_SYSTEM) != 0; return !allowReminders && !allowCalls && !allowMessages && !allowEvents - && !allowRepeatCallers && !areChannelsBypassingDnd; + && !allowRepeatCallers && !areChannelsBypassingDnd && !allowSystem; } /** - * Determines whether dnd behavior should mute all sounds controlled by ringer + * Determines whether dnd behavior should mute all sounds */ public static boolean areAllZenBehaviorSoundsMuted(NotificationManager.Policy policy) { boolean allowAlarms = (policy.priorityCategories & Policy.PRIORITY_CATEGORY_ALARMS) != 0; boolean allowMedia = (policy.priorityCategories & Policy.PRIORITY_CATEGORY_MEDIA) != 0; - boolean allowSystem = (policy.priorityCategories & Policy.PRIORITY_CATEGORY_SYSTEM) != 0; - return !allowAlarms && !allowMedia && !allowSystem - && areAllPriorityOnlyNotificationZenSoundsMuted(policy); + return !allowAlarms && !allowMedia && areAllPriorityOnlyRingerSoundsMuted(policy); } /** @@ -1943,24 +1942,25 @@ public class ZenModeConfig implements Parcelable { return zen == Global.ZEN_MODE_NO_INTERRUPTIONS || zen == Global.ZEN_MODE_ALARMS || (zen == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS - && ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(consolidatedPolicy)); + && ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(consolidatedPolicy)); } /** - * Determines whether dnd behavior should mute all sounds controlled by ringer + * Determines whether dnd behavior should mute all ringer-controlled sounds + * This includes notification, ringer and system sounds */ - public static boolean areAllPriorityOnlyNotificationZenSoundsMuted(ZenModeConfig config) { + public static boolean areAllPriorityOnlyRingerSoundsMuted(ZenModeConfig config) { return !config.allowReminders && !config.allowCalls && !config.allowMessages && !config.allowEvents && !config.allowRepeatCallers - && !config.areChannelsBypassingDnd; + && !config.areChannelsBypassingDnd && !config.allowSystem; } /** - * Determines whether all dnd mutes all sounds + * Determines whether dnd mutes all sounds */ public static boolean areAllZenBehaviorSoundsMuted(ZenModeConfig config) { - return !config.allowAlarms && !config.allowMedia && !config.allowSystem - && areAllPriorityOnlyNotificationZenSoundsMuted(config); + return !config.allowAlarms && !config.allowMedia + && areAllPriorityOnlyRingerSoundsMuted(config); } /** diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java index edea92f5952a7..2c70fb4c50ecc 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java @@ -621,7 +621,9 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa .PRIORITY_CATEGORY_MEDIA) == 0; boolean disallowSystem = (policy.priorityCategories & NotificationManager.Policy .PRIORITY_CATEGORY_SYSTEM) == 0; - boolean disallowRinger = ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(policy); + // ringer controls notifications, ringer and system sounds, so only disallow ringer changes + // if all relevant (notifications + ringer + system) sounds are not allowed to bypass DND + boolean disallowRinger = ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(policy); if (mState.disallowAlarms == disallowAlarms && mState.disallowMedia == disallowMedia && mState.disallowRinger == disallowRinger diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 77b3feec700e2..ccbe08f475c34 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -3854,7 +3854,7 @@ public class AudioService extends IAudioService.Stub final boolean muteSystem = (zenPolicy.priorityCategories & NotificationManager.Policy.PRIORITY_CATEGORY_SYSTEM) == 0; final boolean muteNotificationAndRing = ZenModeConfig - .areAllPriorityOnlyNotificationZenSoundsMuted( + .areAllPriorityOnlyRingerSoundsMuted( mNm.getConsolidatedNotificationPolicy()); return muteAlarms && isAlarm(streamType) || muteMedia && isMedia(streamType) @@ -3867,16 +3867,26 @@ public class AudioService extends IAudioService.Stub } /** - * DND total silence: media and alarms streams are tied to the muted ringer + * Notifications, ringer and system sounds are controlled by the 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 + * DND total silence: media and alarms streams can be muted by DND + * DND alarms only: no streams additionally controlled by DND + * DND priority only: alarms, media, system streams can be muted by DND based on * zenPolicy (this method determines which streams) * @return true if changed, else false */ private boolean updateZenModeAffectedStreams() { + if (!mSystemReady) { + return false; + } + int zenModeAffectedStreams = 0; - if (mSystemReady && mNm.getZenMode() == Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) { + final int zenMode = mNm.getZenMode(); + + if (zenMode == Settings.Global.ZEN_MODE_NO_INTERRUPTIONS) { + zenModeAffectedStreams |= 1 << AudioManager.STREAM_ALARM; + zenModeAffectedStreams |= 1 << AudioManager.STREAM_MUSIC; + } else if (zenMode == Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) { NotificationManager.Policy zenPolicy = mNm.getConsolidatedNotificationPolicy(); if ((zenPolicy.priorityCategories & NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS) == 0) { @@ -3888,6 +3898,8 @@ public class AudioService extends IAudioService.Stub zenModeAffectedStreams |= 1 << AudioManager.STREAM_MUSIC; } + // even if zen isn't muting the system stream, the ringer mode can still mute + // the system stream if ((zenPolicy.priorityCategories & NotificationManager.Policy.PRIORITY_CATEGORY_SYSTEM) == 0) { zenModeAffectedStreams |= 1 << AudioManager.STREAM_SYSTEM; diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java index f63aa52560783..65109230bb9a1 100644 --- a/services/core/java/com/android/server/notification/ZenModeHelper.java +++ b/services/core/java/com/android/server/notification/ZenModeHelper.java @@ -1179,7 +1179,7 @@ public class ZenModeHelper { if (mZenMode == Global.ZEN_MODE_OFF || (mZenMode == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS - && !ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(mConfig))) { + && !ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(mConfig))) { // in priority only with ringer not muted, save ringer mode changes // in dnd off, save ringer mode changes setPreviousRingerModeSetting(ringerModeNew); @@ -1200,7 +1200,7 @@ public class ZenModeHelper { && (mZenMode == Global.ZEN_MODE_NO_INTERRUPTIONS || mZenMode == Global.ZEN_MODE_ALARMS || (mZenMode == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS - && ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted( + && ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted( mConfig)))) { newZen = Global.ZEN_MODE_OFF; } else if (mZenMode != Global.ZEN_MODE_OFF) { @@ -1264,29 +1264,21 @@ public class ZenModeHelper { @Override public int getRingerModeAffectedStreams(int streams) { - // ringtone and notification streams are always affected by ringer mode - // system stream is affected by ringer mode when not in priority-only + // ringtone, notification and system streams are always affected by ringer mode + // zen muting is handled in AudioService.java's mZenModeAffectedStreams streams |= (1 << AudioSystem.STREAM_RING) | (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 + // alarm and music streams affected by ringer mode (cannot be adjusted) when in + // total silence streams |= (1 << AudioSystem.STREAM_ALARM) | (1 << AudioSystem.STREAM_MUSIC); } else { streams &= ~((1 << AudioSystem.STREAM_ALARM) | (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/ZenModeConfigTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java index dcab78ede2876..3d872237d8d46 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java @@ -16,9 +16,10 @@ package com.android.server.notification; -import static junit.framework.Assert.assertEquals; +import static junit.framework.TestCase.assertEquals; import static junit.framework.TestCase.assertFalse; import static junit.framework.TestCase.assertNull; +import static junit.framework.TestCase.assertTrue; import android.app.NotificationManager.Policy; import android.content.ComponentName; @@ -52,18 +53,18 @@ public class ZenModeConfigTest extends UiServiceTestCase { @Test public void testPriorityOnlyMutingAllNotifications() { - ZenModeConfig config = getMutedNotificationsConfig(); - assertEquals(true, ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(config)); + ZenModeConfig config = getMutedRingerConfig(); + assertTrue(ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(config)); config.allowReminders = true; - assertEquals(false, ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(config)); + assertFalse(ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(config)); config.allowReminders = false; config.areChannelsBypassingDnd = true; - assertEquals(false, ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(config)); + assertFalse(ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(config)); config.areChannelsBypassingDnd = false; - assertEquals(true, ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(config)); + assertTrue(ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(config)); } @Test @@ -106,26 +107,26 @@ public class ZenModeConfigTest extends UiServiceTestCase { @Test public void testPriorityOnlyMutingAll() { ZenModeConfig config = getMutedAllConfig(); - assertEquals(true, ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(config)); - assertEquals(true, ZenModeConfig.areAllZenBehaviorSoundsMuted(config)); + assertTrue(ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(config)); + assertTrue(ZenModeConfig.areAllZenBehaviorSoundsMuted(config)); config.allowReminders = true; - assertEquals(false, ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(config)); - assertEquals(false, ZenModeConfig.areAllZenBehaviorSoundsMuted(config)); + assertFalse(ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(config)); + assertFalse(ZenModeConfig.areAllZenBehaviorSoundsMuted(config)); config.allowReminders = false; config.areChannelsBypassingDnd = true; - assertEquals(false, ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(config)); - assertEquals(false, ZenModeConfig.areAllZenBehaviorSoundsMuted(config)); + assertFalse(ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(config)); + assertFalse(ZenModeConfig.areAllZenBehaviorSoundsMuted(config)); config.areChannelsBypassingDnd = false; config.allowAlarms = true; - assertEquals(true, ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(config)); - assertEquals(false, ZenModeConfig.areAllZenBehaviorSoundsMuted(config)); + assertTrue(ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(config)); + assertFalse(ZenModeConfig.areAllZenBehaviorSoundsMuted(config)); config.allowAlarms = false; - assertEquals(true, ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(config)); - assertEquals(true, ZenModeConfig.areAllZenBehaviorSoundsMuted(config)); + assertTrue(ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(config)); + assertTrue(ZenModeConfig.areAllZenBehaviorSoundsMuted(config)); } @Test @@ -200,14 +201,14 @@ public class ZenModeConfigTest extends UiServiceTestCase { assertEquals(rule.zenMode, fromXml.zenMode); } - private ZenModeConfig getMutedNotificationsConfig() { + private ZenModeConfig getMutedRingerConfig() { ZenModeConfig config = new ZenModeConfig(); - // Allow alarms, media, and system + // Allow alarms, media config.allowAlarms = true; config.allowMedia = true; - config.allowSystem = true; - // All notification sounds are not allowed + // All sounds that respect the ringer are not allowed + config.allowSystem = false; config.allowCalls = false; config.allowRepeatCallers = false; config.allowMessages = false; 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 89364500fd80d..99771b91ee2ab 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java @@ -487,7 +487,6 @@ public class ZenModeHelperTest extends UiServiceTestCase { 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; @@ -503,8 +502,9 @@ public class ZenModeHelperTest extends UiServiceTestCase { 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 + // even when ringer is muted (since all ringer sounds cannot bypass DND), + // system stream is still affected by ringer mode + mZenModeHelperSpy.mConfig.allowSystem = false; mZenModeHelperSpy.mConfig.allowReminders = false; mZenModeHelperSpy.mConfig.allowCalls = false; mZenModeHelperSpy.mConfig.allowMessages = false; @@ -519,7 +519,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { assertTrue((ringerMutedRingerModeAffectedStreams & (1 << AudioSystem.STREAM_NOTIFICATION)) != 0); assertTrue((ringerMutedRingerModeAffectedStreams & (1 << AudioSystem.STREAM_SYSTEM)) - == 0); + != 0); assertTrue((ringerMutedRingerModeAffectedStreams & (1 << AudioSystem.STREAM_ALARM)) == 0); assertTrue((ringerMutedRingerModeAffectedStreams & (1 << AudioSystem.STREAM_MUSIC)) == 0); }