From d9c3cf855f5dd830d2e90bef8c906b958bc74fa9 Mon Sep 17 00:00:00 2001 From: Behnam Heydarshahi Date: Tue, 31 Jan 2023 21:04:32 +0000 Subject: [PATCH] Muting ring volume slider disables notification With volume_separate_notification flag enbaled, muting ring volume slice will cause notification volume slice to gray out. There used to be a bug in which notification slice would not get updated in response to a change in ring volume mute/unmute broadcast. The resulting erroneous behavior was notification slider would get to zero but not get grayed out. To fix that bug, VolumeSliceHelper listens to ring stream mute/unmute broadcasts and forwards them to notification slice. Bug: b/266072907 Test: make DEBUG_ROBOLECTRIC=1 ROBOTEST_FILTER="NotificationVolumePreferenceControllerTest|VolumeSliceHelperTest" RunSettingsRoboTests -j40 Change-Id: I2ab51f1272bf99a0c3d9ca285354052d00910c90 --- res/values/strings.xml | 3 ++ res/xml/sound_settings.xml | 4 +- ...otificationVolumePreferenceController.java | 39 ++++++++++++------- ...odeAffectedVolumePreferenceController.java | 11 +++++- .../settings/slices/VolumeSliceHelper.java | 26 ++++++++++++- ...icationVolumePreferenceControllerTest.java | 23 +++++++++-- .../slices/VolumeSliceHelperTest.java | 39 ++++++++++++++++++- 7 files changed, 121 insertions(+), 24 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index d2871ea3040..ecf378d5bd6 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -8828,6 +8828,9 @@ Notification volume + + Unavailable because ring is muted + Phone ringtone diff --git a/res/xml/sound_settings.xml b/res/xml/sound_settings.xml index a84b0aefcd2..7181e80b658 100644 --- a/res/xml/sound_settings.xml +++ b/res/xml/sound_settings.xml @@ -86,8 +86,8 @@ android:icon="@drawable/ic_notifications" android:title="@string/notification_volume_option_title" android:order="-150" - settings:controller= - "com.android.settings.notification.NotificationVolumePreferenceController"/> + settings:controller="com.android.settings.notification.NotificationVolumePreferenceController" + settings:unavailableSliceSubtitle="@string/notification_volume_disabled_summary"/> entry : sRegisteredUri.entrySet()) { if (entry.getValue() == inputType) { diff --git a/tests/robotests/src/com/android/settings/notification/NotificationVolumePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/NotificationVolumePreferenceControllerTest.java index 7e7ad10d8c1..594ef625ffb 100644 --- a/tests/robotests/src/com/android/settings/notification/NotificationVolumePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/NotificationVolumePreferenceControllerTest.java @@ -198,6 +198,7 @@ public class NotificationVolumePreferenceControllerTest { com.android.settings.R.bool.config_show_notification_volume)).thenReturn(true); // block the alternative condition to enable controller when(mTelephonyManager.isVoiceCapable()).thenReturn(true); + when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL); DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI, SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, "false", false); @@ -217,8 +218,8 @@ public class NotificationVolumePreferenceControllerTest { SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, Boolean.toString(true), false); - assertThat(controller.getAvailabilityStatus() - == BasePreferenceController.AVAILABLE).isTrue(); + assertThat(controller.getAvailabilityStatus()).isEqualTo( + BasePreferenceController.AVAILABLE); } @Test @@ -233,9 +234,10 @@ public class NotificationVolumePreferenceControllerTest { // block the alternative condition to enable controller when(mTelephonyManager.isVoiceCapable()).thenReturn(true); + when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI, SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, "true", false); - NotificationVolumePreferenceController controller = new NotificationVolumePreferenceController(mContext); @@ -254,4 +256,19 @@ public class NotificationVolumePreferenceControllerTest { == BasePreferenceController.UNSUPPORTED_ON_DEVICE).isTrue(); } + @Test + public void ringerModeSilent_unaliased_getAvailability_returnsDisabled() { + when(mResources.getBoolean( + com.android.settings.R.bool.config_show_notification_volume)).thenReturn(true); + when(mHelper.isSingleVolume()).thenReturn(false); + + when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT); + + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI, + SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, "true", false); + + assertThat(mController.getAvailabilityStatus()) + .isEqualTo(BasePreferenceController.DISABLED_DEPENDENT_SETTING); + } + } diff --git a/tests/robotests/src/com/android/settings/slices/VolumeSliceHelperTest.java b/tests/robotests/src/com/android/settings/slices/VolumeSliceHelperTest.java index 2ceeb253c9c..b4abd8c0a58 100644 --- a/tests/robotests/src/com/android/settings/slices/VolumeSliceHelperTest.java +++ b/tests/robotests/src/com/android/settings/slices/VolumeSliceHelperTest.java @@ -34,6 +34,7 @@ import android.media.AudioManager; import android.net.Uri; import com.android.settings.notification.MediaVolumePreferenceController; +import com.android.settings.notification.NotificationVolumePreferenceController; import com.android.settings.notification.RingVolumePreferenceController; import com.android.settings.notification.SeparateRingVolumePreferenceController; import com.android.settings.notification.VolumeSeekBarPreferenceController; @@ -64,6 +65,7 @@ public class VolumeSliceHelperTest { private VolumeSeekBarPreferenceController mMediaController; private VolumeSeekBarPreferenceController mRingController; private VolumeSeekBarPreferenceController mSeparateRingController; + private VolumeSeekBarPreferenceController mNotificationController; @Before public void setUp() { @@ -72,8 +74,9 @@ public class VolumeSliceHelperTest { when(mContext.getContentResolver()).thenReturn(mResolver); mMediaController = new MediaVolumePreferenceController(mContext); - mSeparateRingController = new SeparateRingVolumePreferenceController(mContext); mRingController = new RingVolumePreferenceController(mContext); + mSeparateRingController = new SeparateRingVolumePreferenceController(mContext); + mNotificationController = new NotificationVolumePreferenceController(mContext); mIntent = createIntent(AudioManager.VOLUME_CHANGED_ACTION) .putExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, 1) @@ -238,6 +241,40 @@ public class VolumeSliceHelperTest { verify(mResolver).notifyChange(mMediaController.getSliceUri(), null); } + /** + * Without this test passing, when notification is separated from ring and its value is already + * zero, setting ringermode to silent would not disable notification slider. + * Note: the above scenario happens only in volume panel where controllers do not get to + * register for events such as RINGER_MODE_CHANGE. + */ + @Test + public void onReceive_ringVolumeMuted_shouldNotifyChangeNotificationSlice() { + final Intent intent = createIntent(AudioManager.STREAM_MUTE_CHANGED_ACTION) + .putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mRingController.getAudioStream()); + registerIntentToUri(mRingController); + registerIntentToUri(mNotificationController); + + VolumeSliceHelper.onReceive(mContext, intent); + + verify(mResolver).notifyChange(mNotificationController.getSliceUri(), null); + } + + /** + * Notifying notification slice on ring mute does not mean it should not notify ring slice. + * Rather, it should notify both slices. + */ + @Test + public void onReceive_ringVolumeMuted_shouldNotifyChangeRingSlice() { + final Intent intent = createIntent(AudioManager.STREAM_MUTE_CHANGED_ACTION) + .putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mRingController.getAudioStream()); + registerIntentToUri(mRingController); + registerIntentToUri(mNotificationController); + + VolumeSliceHelper.onReceive(mContext, intent); + + verify(mResolver).notifyChange(mRingController.getSliceUri(), null); + } + @Test public void onReceive_streamDevicesChanged_shouldNotifyChange() { final Intent intent = createIntent(AudioManager.STREAM_DEVICES_CHANGED_ACTION)