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"/>
activityFilters, Intent intent) {
activityFilters.add(new ActivityFilter(COMPONENT_NAME_WILDCARD, intent.getAction()));
}
- private void addActivityFilter(Set activityFilters,
+ private void addActivityFilter(Collection activityFilters,
Class extends Activity> activityClass) {
activityFilters.add(new ActivityFilter(new ComponentName(mContext, activityClass),
null /* intentAction */));
diff --git a/src/com/android/settings/activityembedding/ActivityEmbeddingUtils.java b/src/com/android/settings/activityembedding/ActivityEmbeddingUtils.java
index fdf13142cb8..63ea9cd519d 100644
--- a/src/com/android/settings/activityembedding/ActivityEmbeddingUtils.java
+++ b/src/com/android/settings/activityembedding/ActivityEmbeddingUtils.java
@@ -30,29 +30,25 @@ import com.android.settings.R;
/** An util class collecting all common methods for the embedding activity features. */
public class ActivityEmbeddingUtils {
// The smallest value of current width of the window when the split should be used.
- private static final float MIN_CURRENT_SCREEN_SPLIT_WIDTH_DP = 720f;
+ private static final int MIN_CURRENT_SCREEN_SPLIT_WIDTH_DP = 720;
// The smallest value of the smallest-width (sw) of the window in any rotation when
// the split should be used.
- private static final float MIN_SMALLEST_SCREEN_SPLIT_WIDTH_DP = 600f;
+ private static final int MIN_SMALLEST_SCREEN_SPLIT_WIDTH_DP = 600;
// The minimum width of the activity to show the regular homepage layout.
private static final float MIN_REGULAR_HOMEPAGE_LAYOUT_WIDTH_DP = 380f;
private static final String TAG = "ActivityEmbeddingUtils";
- /** Get the smallest pixel value of width of the window when the split should be used. */
- public static int getMinCurrentScreenSplitWidthPx(Context context) {
- final DisplayMetrics dm = context.getResources().getDisplayMetrics();
- return (int) TypedValue.applyDimension(
- TypedValue.COMPLEX_UNIT_DIP, MIN_CURRENT_SCREEN_SPLIT_WIDTH_DP, dm);
+ /** Get the smallest width dp of the window when the split should be used. */
+ public static int getMinCurrentScreenSplitWidthDp() {
+ return MIN_CURRENT_SCREEN_SPLIT_WIDTH_DP;
}
/**
- * Get the smallest pixel value of the smallest-width (sw) of the window in any rotation when
+ * Get the smallest dp value of the smallest-width (sw) of the window in any rotation when
* the split should be used.
*/
- public static int getMinSmallestScreenSplitWidthPx(Context context) {
- final DisplayMetrics dm = context.getResources().getDisplayMetrics();
- return (int) TypedValue.applyDimension(
- TypedValue.COMPLEX_UNIT_DIP, MIN_SMALLEST_SCREEN_SPLIT_WIDTH_DP, dm);
+ public static int getMinSmallestScreenSplitWidthDp() {
+ return MIN_SMALLEST_SCREEN_SPLIT_WIDTH_DP;
}
/**
@@ -67,7 +63,7 @@ public class ActivityEmbeddingUtils {
public static boolean isEmbeddingActivityEnabled(Context context) {
final boolean isFlagEnabled = FeatureFlagUtils.isEnabled(context,
FeatureFlagUtils.SETTINGS_SUPPORT_LARGE_SCREEN);
- final boolean isSplitSupported = SplitController.getInstance().isSplitSupported();
+ final boolean isSplitSupported = SplitController.getInstance(context).isSplitSupported();
Log.d(TAG, "isFlagEnabled = " + isFlagEnabled);
Log.d(TAG, "isSplitSupported = " + isSplitSupported);
diff --git a/src/com/android/settings/homepage/SettingsHomepageActivity.java b/src/com/android/settings/homepage/SettingsHomepageActivity.java
index 2961abbd895..b27f5cc8b66 100644
--- a/src/com/android/settings/homepage/SettingsHomepageActivity.java
+++ b/src/com/android/settings/homepage/SettingsHomepageActivity.java
@@ -56,6 +56,7 @@ import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
+import androidx.window.embedding.ActivityEmbeddingController;
import androidx.window.embedding.SplitController;
import androidx.window.embedding.SplitRule;
@@ -102,7 +103,7 @@ public class SettingsHomepageActivity extends FragmentActivity implements
private View mTwoPaneSuggestionView;
private CategoryMixin mCategoryMixin;
private Set mLoadedListeners;
- private SplitController mSplitController;
+ private ActivityEmbeddingController mActivityEmbeddingController;
private boolean mIsEmbeddingActivityEnabled;
private boolean mIsTwoPane;
// A regular layout shows icons on homepage, whereas a simplified layout doesn't.
@@ -190,8 +191,8 @@ public class SettingsHomepageActivity extends FragmentActivity implements
setupEdgeToEdge();
setContentView(R.layout.settings_homepage_container);
- mSplitController = SplitController.getInstance();
- mIsTwoPane = mSplitController.isActivityEmbedded(this);
+ mActivityEmbeddingController = ActivityEmbeddingController.getInstance(this);
+ mIsTwoPane = mActivityEmbeddingController.isActivityEmbedded(this);
updateAppBarMinHeight();
initHomepageContainer();
@@ -266,7 +267,7 @@ public class SettingsHomepageActivity extends FragmentActivity implements
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
- final boolean newTwoPaneState = mSplitController.isActivityEmbedded(this);
+ final boolean newTwoPaneState = mActivityEmbeddingController.isActivityEmbedded(this);
if (mIsTwoPane != newTwoPaneState) {
mIsTwoPane = newTwoPaneState;
updateHomepageAppBar();
@@ -518,15 +519,15 @@ public class SettingsHomepageActivity extends FragmentActivity implements
new ComponentName(getApplicationContext(), getClass()),
targetComponentName,
targetIntent.getAction(),
- SplitRule.FINISH_ALWAYS,
- SplitRule.FINISH_ALWAYS,
+ SplitRule.FinishBehavior.ALWAYS,
+ SplitRule.FinishBehavior.ALWAYS,
true /* clearTop */);
ActivityEmbeddingRulesController.registerTwoPanePairRule(this,
new ComponentName(getApplicationContext(), Settings.class),
targetComponentName,
targetIntent.getAction(),
- SplitRule.FINISH_ALWAYS,
- SplitRule.FINISH_ALWAYS,
+ SplitRule.FinishBehavior.ALWAYS,
+ SplitRule.FinishBehavior.ALWAYS,
true /* clearTop */);
final UserHandle user = intent.getParcelableExtra(EXTRA_USER_HANDLE, UserHandle.class);
diff --git a/src/com/android/settings/homepage/TopLevelSettings.java b/src/com/android/settings/homepage/TopLevelSettings.java
index 8c122ef2ad6..af553d6393c 100644
--- a/src/com/android/settings/homepage/TopLevelSettings.java
+++ b/src/com/android/settings/homepage/TopLevelSettings.java
@@ -35,7 +35,7 @@ import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceScreen;
import androidx.recyclerview.widget.RecyclerView;
-import androidx.window.embedding.SplitController;
+import androidx.window.embedding.ActivityEmbeddingController;
import com.android.settings.R;
import com.android.settings.Utils;
@@ -65,6 +65,7 @@ public class TopLevelSettings extends DashboardFragment implements SplitLayoutLi
private int mPaddingHorizontal;
private boolean mScrollNeeded = true;
private boolean mFirstStarted = true;
+ private ActivityEmbeddingController mActivityEmbeddingController;
public TopLevelSettings() {
final Bundle args = new Bundle();
@@ -143,7 +144,7 @@ public class TopLevelSettings extends DashboardFragment implements SplitLayoutLi
return;
}
- boolean activityEmbedded = SplitController.getInstance().isActivityEmbedded(getActivity());
+ boolean activityEmbedded = isActivityEmbedded();
if (icicle != null) {
mHighlightMixin = icicle.getParcelable(SAVED_HIGHLIGHT_MIXIN);
mScrollNeeded = !mHighlightMixin.isActivityEmbedded() && activityEmbedded;
@@ -154,6 +155,14 @@ public class TopLevelSettings extends DashboardFragment implements SplitLayoutLi
}
}
+ /** Wrap ActivityEmbeddingController#isActivityEmbedded for testing. */
+ public boolean isActivityEmbedded() {
+ if (mActivityEmbeddingController == null) {
+ mActivityEmbeddingController = ActivityEmbeddingController.getInstance(getActivity());
+ }
+ return mActivityEmbeddingController.isActivityEmbedded(getActivity());
+ }
+
@Override
public void onStart() {
if (mFirstStarted) {
@@ -161,7 +170,7 @@ public class TopLevelSettings extends DashboardFragment implements SplitLayoutLi
FeatureFactory.getFactory(getContext()).getSearchFeatureProvider().sendPreIndexIntent(
getContext());
} else if (mIsEmbeddingActivityEnabled && isOnlyOneActivityInTask()
- && !SplitController.getInstance().isActivityEmbedded(getActivity())) {
+ && !isActivityEmbedded()) {
// Set default highlight menu key for 1-pane homepage since it will show the placeholder
// page once changing back to 2-pane.
Log.i(TAG, "Set default menu key");
@@ -286,7 +295,7 @@ public class TopLevelSettings extends DashboardFragment implements SplitLayoutLi
* 3. the current activity is embedded */
return mHighlightMixin != null
&& TextUtils.equals(pref.getKey(), mHighlightMixin.getHighlightPreferenceKey())
- && SplitController.getInstance().isActivityEmbedded(getActivity());
+ && isActivityEmbedded();
}
/** Show/hide the highlight on the menu entry for the search page presence */
diff --git a/src/com/android/settings/notification/NotificationVolumePreferenceController.java b/src/com/android/settings/notification/NotificationVolumePreferenceController.java
index 4fd2341265f..54d78547d83 100644
--- a/src/com/android/settings/notification/NotificationVolumePreferenceController.java
+++ b/src/com/android/settings/notification/NotificationVolumePreferenceController.java
@@ -51,7 +51,6 @@ public class NotificationVolumePreferenceController extends
private final RingReceiver mReceiver = new RingReceiver();
private final H mHandler = new H();
-
public NotificationVolumePreferenceController(Context context) {
this(context, KEY_NOTIFICATION_VOLUME);
}
@@ -63,7 +62,9 @@ public class NotificationVolumePreferenceController extends
mVibrateIconId = R.drawable.ic_volume_ringer_vibrate;
mSilentIconId = R.drawable.ic_notifications_off_24dp;
- updateRingerMode();
+ if (updateRingerMode()) {
+ updateEnabledState();
+ }
}
/**
@@ -77,12 +78,10 @@ public class NotificationVolumePreferenceController extends
if (mPreference == null) {
setupVolPreference(screen);
}
- mSeparateNotification = isSeparateNotificationConfigEnabled();
- if (mPreference != null) {
- mPreference.setVisible(getAvailabilityStatus() == AVAILABLE);
- }
+
updateEffectsSuppressor();
selectPreferenceIconState();
+ updateEnabledState();
}
/**
@@ -95,15 +94,19 @@ public class NotificationVolumePreferenceController extends
boolean newVal = isSeparateNotificationConfigEnabled();
if (newVal != mSeparateNotification) {
mSeparateNotification = newVal;
- // manually hiding the preference because being unavailable does not do the job
+ // Update UI if config change happens when Sound Settings page is on the foreground
if (mPreference != null) {
- mPreference.setVisible(getAvailabilityStatus() == AVAILABLE);
+ int status = getAvailabilityStatus();
+ mPreference.setVisible(status == AVAILABLE
+ || status == DISABLED_DEPENDENT_SETTING);
+ if (status == DISABLED_DEPENDENT_SETTING) {
+ mPreference.setEnabled(false);
+ }
}
}
}
}
-
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
@Override
public void onResume() {
@@ -126,10 +129,11 @@ public class NotificationVolumePreferenceController extends
@Override
public int getAvailabilityStatus() {
boolean separateNotification = isSeparateNotificationConfigEnabled();
-
return mContext.getResources().getBoolean(R.bool.config_show_notification_volume)
&& !mHelper.isSingleVolume() && separateNotification
- ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
+ ? (mRingerMode == AudioManager.RINGER_MODE_NORMAL
+ ? AVAILABLE : DISABLED_DEPENDENT_SETTING)
+ : UNSUPPORTED_ON_DEVICE;
}
@Override
@@ -158,7 +162,6 @@ public class NotificationVolumePreferenceController extends
if (mVibrator != null && mRingerMode == AudioManager.RINGER_MODE_VIBRATE) {
mMuteIcon = mVibrateIconId;
mPreference.showIcon(mVibrateIconId);
-
} else if (mRingerMode == AudioManager.RINGER_MODE_SILENT
|| mVibrator == null && mRingerMode == AudioManager.RINGER_MODE_VIBRATE) {
mMuteIcon = mSilentIconId;
@@ -175,6 +178,12 @@ public class NotificationVolumePreferenceController extends
}
}
+ private void updateEnabledState() {
+ if (mPreference != null) {
+ mPreference.setEnabled(mRingerMode == AudioManager.RINGER_MODE_NORMAL);
+ }
+ }
+
private final class H extends Handler {
private static final int UPDATE_EFFECTS_SUPPRESSOR = 1;
private static final int UPDATE_RINGER_MODE = 2;
@@ -191,10 +200,13 @@ public class NotificationVolumePreferenceController extends
updateEffectsSuppressor();
break;
case UPDATE_RINGER_MODE:
- updateRingerMode();
+ if (updateRingerMode()) {
+ updateEnabledState();
+ }
break;
case NOTIFICATION_VOLUME_CHANGED:
selectPreferenceIconState();
+ updateEnabledState();
break;
}
}
@@ -239,5 +251,4 @@ public class NotificationVolumePreferenceController extends
}
}
}
-
}
diff --git a/src/com/android/settings/notification/RingerModeAffectedVolumePreferenceController.java b/src/com/android/settings/notification/RingerModeAffectedVolumePreferenceController.java
index 255fe2f1cd3..ec619b468bc 100644
--- a/src/com/android/settings/notification/RingerModeAffectedVolumePreferenceController.java
+++ b/src/com/android/settings/notification/RingerModeAffectedVolumePreferenceController.java
@@ -140,11 +140,18 @@ public abstract class RingerModeAffectedVolumePreferenceController extends
return valueUpdated;
}
- protected void updateRingerMode() {
+ /**
+ * Updates UI Icon in response to ringer mode changes.
+ * @return whether the ringer mode has changed.
+ */
+ protected boolean updateRingerMode() {
final int ringerMode = mHelper.getRingerModeInternal();
- if (mRingerMode == ringerMode) return;
+ if (mRingerMode == ringerMode) {
+ return false;
+ }
mRingerMode = ringerMode;
selectPreferenceIconState();
+ return true;
}
/**
diff --git a/src/com/android/settings/slices/VolumeSliceHelper.java b/src/com/android/settings/slices/VolumeSliceHelper.java
index 486148270c8..1ba177823cc 100644
--- a/src/com/android/settings/slices/VolumeSliceHelper.java
+++ b/src/com/android/settings/slices/VolumeSliceHelper.java
@@ -93,8 +93,9 @@ public class VolumeSliceHelper {
if (AudioManager.VOLUME_CHANGED_ACTION.equals(action)) {
handleVolumeChanged(context, intent);
- } else if (AudioManager.STREAM_MUTE_CHANGED_ACTION.equals(action)
- || AudioManager.STREAM_DEVICES_CHANGED_ACTION.equals(action)) {
+ } else if (AudioManager.STREAM_MUTE_CHANGED_ACTION.equals(action)) {
+ handleMuteChanged(context, intent);
+ } else if (AudioManager.STREAM_DEVICES_CHANGED_ACTION.equals(action)) {
handleStreamChanged(context, intent);
} else {
notifyAllStreamsChanged(context);
@@ -109,8 +110,29 @@ public class VolumeSliceHelper {
}
}
+ /**
+ * When mute is changed, notifyChange on relevant Volume Slice ContentResolvers to mark them
+ * as needing update.
+ *
+ * In addition to the matching stream, we always notifyChange for the Notification stream
+ * when Ring events are issued. This is to make sure that Notification always gets updated
+ * for RingerMode changes, even if Notification's volume is zero and therefore it would not
+ * get its own AudioManager.VOLUME_CHANGED_ACTION.
+ */
+ private static void handleMuteChanged(Context context, Intent intent) {
+ final int inputType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
+ handleStreamChanged(context, inputType);
+ if (inputType == AudioManager.STREAM_RING) {
+ handleStreamChanged(context, AudioManager.STREAM_NOTIFICATION);
+ }
+ }
+
private static void handleStreamChanged(Context context, Intent intent) {
final int inputType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
+ handleStreamChanged(context, inputType);
+ }
+
+ private static void handleStreamChanged(Context context, int inputType) {
synchronized (sRegisteredUri) {
for (Map.Entry entry : sRegisteredUri.entrySet()) {
if (entry.getValue() == inputType) {
diff --git a/src/com/android/settings/widget/HighlightableTopLevelPreferenceAdapter.java b/src/com/android/settings/widget/HighlightableTopLevelPreferenceAdapter.java
index 3cc7ef27f7e..8084a4811d6 100644
--- a/src/com/android/settings/widget/HighlightableTopLevelPreferenceAdapter.java
+++ b/src/com/android/settings/widget/HighlightableTopLevelPreferenceAdapter.java
@@ -30,7 +30,7 @@ import androidx.preference.PreferenceGroup;
import androidx.preference.PreferenceGroupAdapter;
import androidx.preference.PreferenceViewHolder;
import androidx.recyclerview.widget.RecyclerView;
-import androidx.window.embedding.SplitController;
+import androidx.window.embedding.ActivityEmbeddingController;
import com.android.settings.R;
import com.android.settings.Utils;
@@ -250,6 +250,7 @@ public class HighlightableTopLevelPreferenceAdapter extends PreferenceGroupAdapt
}
private boolean isHighlightNeeded() {
- return SplitController.getInstance().isActivityEmbedded(mHomepageActivity);
+ return ActivityEmbeddingController.getInstance(mHomepageActivity)
+ .isActivityEmbedded(mHomepageActivity);
}
}
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)