Improve volume touches
- Change the ringer toggle into a tristate
- Make the tap targets for the output chooser and ringer toggle
larger
- Prevent the slider from capturing extra touches
- Add ripples to the row icon images
Fixes: 72727455
Fixes: 72711039
Fixes: 72627046
Test: runtest systemui
Change-Id: Ie658e9ee813be253dfface827fea86544ef80ed5
diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
index 2d28c9f..4888fb2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
@@ -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;
@@ -32,8 +41,10 @@
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;
@@ -70,13 +81,19 @@
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) {
@@ -111,4 +128,94 @@
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);
+ }
}