Loading packages/SystemUI/res/layout/volume_dialog.xml +2 −1 Original line number Diff line number Diff line Loading @@ -59,6 +59,7 @@ android:gravity="center" android:layout_gravity="end" android:translationZ="8dp" android:clickable="true" android:orientation="vertical" > <TextView Loading @@ -76,7 +77,7 @@ android:id="@+id/ringer_icon" style="@style/VolumeButtons" android:background="?android:selectableItemBackgroundBorderless" android:layout_width="@dimen/volume_button_size" android:layout_width="@dimen/volume_dialog_panel_width" android:layout_height="@dimen/volume_button_size" android:tint="?android:attr/colorAccent" android:soundEffectsEnabled="false" /> Loading packages/SystemUI/res/layout/volume_dialog_row.xml +3 −3 Original line number Diff line number Diff line Loading @@ -63,6 +63,7 @@ android:background="?android:selectableItemBackgroundBorderless" android:contentDescription="@string/accessibility_output_chooser" style="@style/VolumeButtons" android:clickable="false" android:layout_centerVertical="true" android:src="@drawable/ic_swap" android:soundEffectsEnabled="false" /> Loading @@ -70,7 +71,7 @@ </LinearLayout> <FrameLayout android:id="@+id/volume_row_slider_frame" android:padding="10dp" android:padding="0dp" android:layout_width="@dimen/volume_dialog_panel_width" android:layout_height="150dp"> <SeekBar Loading @@ -80,8 +81,6 @@ android:layout_width="150dp" android:layout_height="@dimen/volume_dialog_panel_width" android:layout_gravity="center" android:focusable="true" android:focusableInTouchMode="true" android:rotation="270" /> </FrameLayout> Loading @@ -91,6 +90,7 @@ android:padding="10dp" android:layout_width="@dimen/volume_button_size" android:layout_height="@dimen/volume_button_size" android:background="?android:selectableItemBackgroundBorderless" android:soundEffectsEnabled="false" /> </LinearLayout> No newline at end of file packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java +11 −33 Original line number Diff line number Diff line Loading @@ -36,7 +36,6 @@ import android.content.pm.PackageManager; import android.content.res.ColorStateList; import android.content.res.Resources; import android.graphics.Color; import android.graphics.Rect; import android.graphics.drawable.ColorDrawable; import android.media.AudioManager; import android.media.AudioSystem; Loading @@ -58,7 +57,6 @@ import android.view.View; import android.view.View.AccessibilityDelegate; import android.view.View.OnAttachStateChangeListener; import android.view.View.OnClickListener; import android.view.View.OnTouchListener; import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; Loading Loading @@ -105,6 +103,7 @@ public class VolumeDialogImpl implements VolumeDialog { private CustomDialog mDialog; private ViewGroup mDialogView; private ViewGroup mDialogRowsView; private ViewGroup mFooter; private ImageButton mRingerIcon; private TextView mRingerStatus; private final List<VolumeRow> mRows = new ArrayList<>(); Loading Loading @@ -202,8 +201,9 @@ public class VolumeDialogImpl implements VolumeDialog { hardwareLayout.setOutsideTouchListener(view -> dismiss(DISMISS_REASON_TOUCH_OUTSIDE)); mDialogRowsView = mDialog.findViewById(R.id.volume_dialog_rows); mRingerIcon = mDialog.findViewById(R.id.ringer_icon); mRingerStatus = mDialog.findViewById(R.id.ringer_status); mFooter = mDialog.findViewById(R.id.footer); mRingerIcon = mFooter.findViewById(R.id.ringer_icon); mRingerStatus = mFooter.findViewById(R.id.ringer_status); if (mRows.isEmpty()) { addRow(AudioManager.STREAM_MUSIC, Loading Loading @@ -340,36 +340,8 @@ public class VolumeDialogImpl implements VolumeDialog { row.outputChooser = row.view.findViewById(R.id.output_chooser); row.outputChooser.setOnClickListener(mClickOutputChooser); row.outputChooser.findViewById(R.id.output_chooser_button) .setOnClickListener(mClickOutputChooser); row.connectedDevice = row.view.findViewById(R.id.volume_row_connected_device); // forward events above the slider into the slider row.view.findViewById(R.id.volume_row_slider_frame) .setOnTouchListener(new OnTouchListener() { private final Rect mSliderHitRect = new Rect(); private boolean mDragging; @SuppressLint("ClickableViewAccessibility") @Override public boolean onTouch(View v, MotionEvent event) { row.slider.getHitRect(mSliderHitRect); if (!mDragging && event.getActionMasked() == MotionEvent.ACTION_DOWN && event.getY() < mSliderHitRect.top) { mDragging = true; } if (mDragging) { event.offsetLocation(-mSliderHitRect.left, -mSliderHitRect.top); row.slider.dispatchTouchEvent(event); if (event.getActionMasked() == MotionEvent.ACTION_UP || event.getActionMasked() == MotionEvent.ACTION_CANCEL) { mDragging = false; } return true; } return false; } }); row.icon = row.view.findViewById(R.id.volume_row_icon); row.icon.setImageResource(iconRes); if (row.stream != AudioSystem.STREAM_ACCESSIBILITY) { Loading Loading @@ -412,6 +384,8 @@ public class VolumeDialogImpl implements VolumeDialog { if (ss == null) { return; } // normal -> vibrate -> silent -> normal (skip vibrate if device doesn't have // a vibrator. final boolean hasVibrator = mController.hasVibrator(); if (mState.ringerModeInternal == AudioManager.RINGER_MODE_NORMAL) { if (hasVibrator) { Loading @@ -419,7 +393,12 @@ public class VolumeDialogImpl implements VolumeDialog { } else { final boolean wasZero = ss.level == 0; mController.setStreamVolume(AudioManager.STREAM_RING, wasZero ? 1 : 0); mController.setRingerMode(AudioManager.RINGER_MODE_SILENT, false); } } else if (mState.ringerModeInternal == AudioManager.RINGER_MODE_VIBRATE) { final boolean wasZero = ss.level == 0; mController.setStreamVolume(AudioManager.STREAM_RING, wasZero ? 1 : 0); mController.setRingerMode(AudioManager.RINGER_MODE_SILENT, false); } else { mController.setRingerMode(AudioManager.RINGER_MODE_NORMAL, false); if (ss.level == 0) { Loading Loading @@ -908,7 +887,6 @@ public class VolumeDialogImpl implements VolumeDialog { private final OnClickListener mClickOutputChooser = new OnClickListener() { @Override public void onClick(View v) { // TODO: log dismissH(DISMISS_REASON_OUTPUT_CHOOSER); showOutputChooserH(); } Loading packages/SystemUI/src/com/android/systemui/volume/VolumeUiLayout.java +6 −0 Original line number Diff line number Diff line Loading @@ -309,6 +309,12 @@ public class VolumeUiLayout extends FrameLayout { return super.getOutlineProvider(); } @Override public void setPressed(boolean pressed) { // Ignore presses because it activates the seekbar thumb unnecessarily. } public void setOutsideTouchListener(OnClickListener onClickListener) { mHasOutsideTouch = true; requestLayout(); Loading packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java +109 −2 Original line number Diff line number Diff line Loading @@ -16,12 +16,21 @@ package com.android.systemui.volume; 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_RING; import static com.android.systemui.volume.Events.DISMISS_REASON_UNKNOWN; import static com.android.systemui.volume.Events.SHOW_REASON_UNKNOWN; import static com.android.systemui.volume.VolumeDialogControllerImpl.STREAMS; import static junit.framework.Assert.assertTrue; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.KeyguardManager; import android.media.AudioManager; import android.support.test.filters.SmallTest; Loading @@ -32,8 +41,10 @@ import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.VolumeDialogController; import com.android.systemui.plugins.VolumeDialogController.State; import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper; import org.junit.Before; Loading Loading @@ -70,13 +81,19 @@ public class VolumeDialogImplTest extends SysuiTestCase { mDialog = new VolumeDialogImpl(getContext()); mDialog.init(0, null); VolumeDialogController.State state = new VolumeDialogController.State(); State state = createShellState(); mDialog.onStateChangedH(state); } private State createShellState() { State state = new VolumeDialogController.State(); for (int i = AudioManager.STREAM_VOICE_CALL; i <= AudioManager.STREAM_ACCESSIBILITY; i++) { VolumeDialogController.StreamState ss = new VolumeDialogController.StreamState(); ss.name = STREAMS.get(i); ss.level = 1; state.states.append(i, ss); } mDialog.onStateChangedH(state); return state; } private void navigateViews(View view, Predicate<View> condition) { Loading Loading @@ -111,4 +128,94 @@ public class VolumeDialogImplTest extends SysuiTestCase { mDialog.dismiss(DISMISS_REASON_UNKNOWN); } @Test public void testNoDuplicationOfParentState() { mDialog.show(SHOW_REASON_UNKNOWN); ViewGroup dialog = mDialog.getDialogView(); navigateViews(dialog, view -> !view.isDuplicateParentStateEnabled()); mDialog.dismiss(DISMISS_REASON_UNKNOWN); } @Test public void testNoClickableViewGroups() { mDialog.show(SHOW_REASON_UNKNOWN); ViewGroup dialog = mDialog.getDialogView(); navigateViews(dialog, view -> { if (view instanceof ViewGroup) { return !view.isClickable(); } else { return true; } }); mDialog.dismiss(DISMISS_REASON_UNKNOWN); } @Test public void testTristateToggle_withVibrator() { when(mController.hasVibrator()).thenReturn(true); State state = createShellState(); state.ringerModeInternal = RINGER_MODE_NORMAL; mDialog.onStateChangedH(state); mDialog.show(SHOW_REASON_UNKNOWN); ViewGroup dialog = mDialog.getDialogView(); // click once, verify updates to vibrate dialog.findViewById(R.id.ringer_icon).performClick(); verify(mController, times(1)).setRingerMode(RINGER_MODE_VIBRATE, false); // fake the update back to the dialog with the new ringer mode state = createShellState(); state.ringerModeInternal = RINGER_MODE_VIBRATE; mDialog.onStateChangedH(state); // click once, verify updates to silent dialog.findViewById(R.id.ringer_icon).performClick(); verify(mController, times(1)).setRingerMode(RINGER_MODE_SILENT, false); verify(mController, times(1)).setStreamVolume(STREAM_RING, 0); // fake the update back to the dialog with the new ringer mode state = createShellState(); state.states.get(STREAM_RING).level = 0; state.ringerModeInternal = RINGER_MODE_SILENT; mDialog.onStateChangedH(state); // click once, verify updates to normal dialog.findViewById(R.id.ringer_icon).performClick(); verify(mController, times(1)).setRingerMode(RINGER_MODE_NORMAL, false); verify(mController, times(1)).setStreamVolume(STREAM_RING, 0); } @Test public void testTristateToggle_withoutVibrator() { when(mController.hasVibrator()).thenReturn(false); State state = createShellState(); state.ringerModeInternal = RINGER_MODE_NORMAL; mDialog.onStateChangedH(state); mDialog.show(SHOW_REASON_UNKNOWN); ViewGroup dialog = mDialog.getDialogView(); // click once, verify updates to silent dialog.findViewById(R.id.ringer_icon).performClick(); verify(mController, times(1)).setRingerMode(RINGER_MODE_SILENT, false); verify(mController, times(1)).setStreamVolume(STREAM_RING, 0); // fake the update back to the dialog with the new ringer mode state = createShellState(); state.states.get(STREAM_RING).level = 0; state.ringerModeInternal = RINGER_MODE_SILENT; mDialog.onStateChangedH(state); // click once, verify updates to normal dialog.findViewById(R.id.ringer_icon).performClick(); verify(mController, times(1)).setRingerMode(RINGER_MODE_NORMAL, false); verify(mController, times(1)).setStreamVolume(STREAM_RING, 0); } } Loading
packages/SystemUI/res/layout/volume_dialog.xml +2 −1 Original line number Diff line number Diff line Loading @@ -59,6 +59,7 @@ android:gravity="center" android:layout_gravity="end" android:translationZ="8dp" android:clickable="true" android:orientation="vertical" > <TextView Loading @@ -76,7 +77,7 @@ android:id="@+id/ringer_icon" style="@style/VolumeButtons" android:background="?android:selectableItemBackgroundBorderless" android:layout_width="@dimen/volume_button_size" android:layout_width="@dimen/volume_dialog_panel_width" android:layout_height="@dimen/volume_button_size" android:tint="?android:attr/colorAccent" android:soundEffectsEnabled="false" /> Loading
packages/SystemUI/res/layout/volume_dialog_row.xml +3 −3 Original line number Diff line number Diff line Loading @@ -63,6 +63,7 @@ android:background="?android:selectableItemBackgroundBorderless" android:contentDescription="@string/accessibility_output_chooser" style="@style/VolumeButtons" android:clickable="false" android:layout_centerVertical="true" android:src="@drawable/ic_swap" android:soundEffectsEnabled="false" /> Loading @@ -70,7 +71,7 @@ </LinearLayout> <FrameLayout android:id="@+id/volume_row_slider_frame" android:padding="10dp" android:padding="0dp" android:layout_width="@dimen/volume_dialog_panel_width" android:layout_height="150dp"> <SeekBar Loading @@ -80,8 +81,6 @@ android:layout_width="150dp" android:layout_height="@dimen/volume_dialog_panel_width" android:layout_gravity="center" android:focusable="true" android:focusableInTouchMode="true" android:rotation="270" /> </FrameLayout> Loading @@ -91,6 +90,7 @@ android:padding="10dp" android:layout_width="@dimen/volume_button_size" android:layout_height="@dimen/volume_button_size" android:background="?android:selectableItemBackgroundBorderless" android:soundEffectsEnabled="false" /> </LinearLayout> No newline at end of file
packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java +11 −33 Original line number Diff line number Diff line Loading @@ -36,7 +36,6 @@ import android.content.pm.PackageManager; import android.content.res.ColorStateList; import android.content.res.Resources; import android.graphics.Color; import android.graphics.Rect; import android.graphics.drawable.ColorDrawable; import android.media.AudioManager; import android.media.AudioSystem; Loading @@ -58,7 +57,6 @@ import android.view.View; import android.view.View.AccessibilityDelegate; import android.view.View.OnAttachStateChangeListener; import android.view.View.OnClickListener; import android.view.View.OnTouchListener; import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; Loading Loading @@ -105,6 +103,7 @@ public class VolumeDialogImpl implements VolumeDialog { private CustomDialog mDialog; private ViewGroup mDialogView; private ViewGroup mDialogRowsView; private ViewGroup mFooter; private ImageButton mRingerIcon; private TextView mRingerStatus; private final List<VolumeRow> mRows = new ArrayList<>(); Loading Loading @@ -202,8 +201,9 @@ public class VolumeDialogImpl implements VolumeDialog { hardwareLayout.setOutsideTouchListener(view -> dismiss(DISMISS_REASON_TOUCH_OUTSIDE)); mDialogRowsView = mDialog.findViewById(R.id.volume_dialog_rows); mRingerIcon = mDialog.findViewById(R.id.ringer_icon); mRingerStatus = mDialog.findViewById(R.id.ringer_status); mFooter = mDialog.findViewById(R.id.footer); mRingerIcon = mFooter.findViewById(R.id.ringer_icon); mRingerStatus = mFooter.findViewById(R.id.ringer_status); if (mRows.isEmpty()) { addRow(AudioManager.STREAM_MUSIC, Loading Loading @@ -340,36 +340,8 @@ public class VolumeDialogImpl implements VolumeDialog { row.outputChooser = row.view.findViewById(R.id.output_chooser); row.outputChooser.setOnClickListener(mClickOutputChooser); row.outputChooser.findViewById(R.id.output_chooser_button) .setOnClickListener(mClickOutputChooser); row.connectedDevice = row.view.findViewById(R.id.volume_row_connected_device); // forward events above the slider into the slider row.view.findViewById(R.id.volume_row_slider_frame) .setOnTouchListener(new OnTouchListener() { private final Rect mSliderHitRect = new Rect(); private boolean mDragging; @SuppressLint("ClickableViewAccessibility") @Override public boolean onTouch(View v, MotionEvent event) { row.slider.getHitRect(mSliderHitRect); if (!mDragging && event.getActionMasked() == MotionEvent.ACTION_DOWN && event.getY() < mSliderHitRect.top) { mDragging = true; } if (mDragging) { event.offsetLocation(-mSliderHitRect.left, -mSliderHitRect.top); row.slider.dispatchTouchEvent(event); if (event.getActionMasked() == MotionEvent.ACTION_UP || event.getActionMasked() == MotionEvent.ACTION_CANCEL) { mDragging = false; } return true; } return false; } }); row.icon = row.view.findViewById(R.id.volume_row_icon); row.icon.setImageResource(iconRes); if (row.stream != AudioSystem.STREAM_ACCESSIBILITY) { Loading Loading @@ -412,6 +384,8 @@ public class VolumeDialogImpl implements VolumeDialog { if (ss == null) { return; } // normal -> vibrate -> silent -> normal (skip vibrate if device doesn't have // a vibrator. final boolean hasVibrator = mController.hasVibrator(); if (mState.ringerModeInternal == AudioManager.RINGER_MODE_NORMAL) { if (hasVibrator) { Loading @@ -419,7 +393,12 @@ public class VolumeDialogImpl implements VolumeDialog { } else { final boolean wasZero = ss.level == 0; mController.setStreamVolume(AudioManager.STREAM_RING, wasZero ? 1 : 0); mController.setRingerMode(AudioManager.RINGER_MODE_SILENT, false); } } else if (mState.ringerModeInternal == AudioManager.RINGER_MODE_VIBRATE) { final boolean wasZero = ss.level == 0; mController.setStreamVolume(AudioManager.STREAM_RING, wasZero ? 1 : 0); mController.setRingerMode(AudioManager.RINGER_MODE_SILENT, false); } else { mController.setRingerMode(AudioManager.RINGER_MODE_NORMAL, false); if (ss.level == 0) { Loading Loading @@ -908,7 +887,6 @@ public class VolumeDialogImpl implements VolumeDialog { private final OnClickListener mClickOutputChooser = new OnClickListener() { @Override public void onClick(View v) { // TODO: log dismissH(DISMISS_REASON_OUTPUT_CHOOSER); showOutputChooserH(); } Loading
packages/SystemUI/src/com/android/systemui/volume/VolumeUiLayout.java +6 −0 Original line number Diff line number Diff line Loading @@ -309,6 +309,12 @@ public class VolumeUiLayout extends FrameLayout { return super.getOutlineProvider(); } @Override public void setPressed(boolean pressed) { // Ignore presses because it activates the seekbar thumb unnecessarily. } public void setOutsideTouchListener(OnClickListener onClickListener) { mHasOutsideTouch = true; requestLayout(); Loading
packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java +109 −2 Original line number Diff line number Diff line Loading @@ -16,12 +16,21 @@ package com.android.systemui.volume; 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_RING; import static com.android.systemui.volume.Events.DISMISS_REASON_UNKNOWN; import static com.android.systemui.volume.Events.SHOW_REASON_UNKNOWN; import static com.android.systemui.volume.VolumeDialogControllerImpl.STREAMS; import static junit.framework.Assert.assertTrue; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.KeyguardManager; import android.media.AudioManager; import android.support.test.filters.SmallTest; Loading @@ -32,8 +41,10 @@ import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.VolumeDialogController; import com.android.systemui.plugins.VolumeDialogController.State; import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper; import org.junit.Before; Loading Loading @@ -70,13 +81,19 @@ public class VolumeDialogImplTest extends SysuiTestCase { mDialog = new VolumeDialogImpl(getContext()); mDialog.init(0, null); VolumeDialogController.State state = new VolumeDialogController.State(); State state = createShellState(); mDialog.onStateChangedH(state); } private State createShellState() { State state = new VolumeDialogController.State(); for (int i = AudioManager.STREAM_VOICE_CALL; i <= AudioManager.STREAM_ACCESSIBILITY; i++) { VolumeDialogController.StreamState ss = new VolumeDialogController.StreamState(); ss.name = STREAMS.get(i); ss.level = 1; state.states.append(i, ss); } mDialog.onStateChangedH(state); return state; } private void navigateViews(View view, Predicate<View> condition) { Loading Loading @@ -111,4 +128,94 @@ public class VolumeDialogImplTest extends SysuiTestCase { mDialog.dismiss(DISMISS_REASON_UNKNOWN); } @Test public void testNoDuplicationOfParentState() { mDialog.show(SHOW_REASON_UNKNOWN); ViewGroup dialog = mDialog.getDialogView(); navigateViews(dialog, view -> !view.isDuplicateParentStateEnabled()); mDialog.dismiss(DISMISS_REASON_UNKNOWN); } @Test public void testNoClickableViewGroups() { mDialog.show(SHOW_REASON_UNKNOWN); ViewGroup dialog = mDialog.getDialogView(); navigateViews(dialog, view -> { if (view instanceof ViewGroup) { return !view.isClickable(); } else { return true; } }); mDialog.dismiss(DISMISS_REASON_UNKNOWN); } @Test public void testTristateToggle_withVibrator() { when(mController.hasVibrator()).thenReturn(true); State state = createShellState(); state.ringerModeInternal = RINGER_MODE_NORMAL; mDialog.onStateChangedH(state); mDialog.show(SHOW_REASON_UNKNOWN); ViewGroup dialog = mDialog.getDialogView(); // click once, verify updates to vibrate dialog.findViewById(R.id.ringer_icon).performClick(); verify(mController, times(1)).setRingerMode(RINGER_MODE_VIBRATE, false); // fake the update back to the dialog with the new ringer mode state = createShellState(); state.ringerModeInternal = RINGER_MODE_VIBRATE; mDialog.onStateChangedH(state); // click once, verify updates to silent dialog.findViewById(R.id.ringer_icon).performClick(); verify(mController, times(1)).setRingerMode(RINGER_MODE_SILENT, false); verify(mController, times(1)).setStreamVolume(STREAM_RING, 0); // fake the update back to the dialog with the new ringer mode state = createShellState(); state.states.get(STREAM_RING).level = 0; state.ringerModeInternal = RINGER_MODE_SILENT; mDialog.onStateChangedH(state); // click once, verify updates to normal dialog.findViewById(R.id.ringer_icon).performClick(); verify(mController, times(1)).setRingerMode(RINGER_MODE_NORMAL, false); verify(mController, times(1)).setStreamVolume(STREAM_RING, 0); } @Test public void testTristateToggle_withoutVibrator() { when(mController.hasVibrator()).thenReturn(false); State state = createShellState(); state.ringerModeInternal = RINGER_MODE_NORMAL; mDialog.onStateChangedH(state); mDialog.show(SHOW_REASON_UNKNOWN); ViewGroup dialog = mDialog.getDialogView(); // click once, verify updates to silent dialog.findViewById(R.id.ringer_icon).performClick(); verify(mController, times(1)).setRingerMode(RINGER_MODE_SILENT, false); verify(mController, times(1)).setStreamVolume(STREAM_RING, 0); // fake the update back to the dialog with the new ringer mode state = createShellState(); state.states.get(STREAM_RING).level = 0; state.ringerModeInternal = RINGER_MODE_SILENT; mDialog.onStateChangedH(state); // click once, verify updates to normal dialog.findViewById(R.id.ringer_icon).performClick(); verify(mController, times(1)).setRingerMode(RINGER_MODE_NORMAL, false); verify(mController, times(1)).setStreamVolume(STREAM_RING, 0); } }