diff options
| author | 2018-02-01 00:14:41 +0000 | |
|---|---|---|
| committer | 2018-02-01 00:14:41 +0000 | |
| commit | 84d6ca731b0e33dc8380c3649f888d6ee4be25ec (patch) | |
| tree | df5e198884a99185a96d4345e0d036d0b1e9c23d | |
| parent | 5f2a4ef763ef416c5954836c1d178188c38765d6 (diff) | |
| parent | 45d4ab077ba93bdfcb8eefb425931bc0364372dd (diff) | |
Merge "Improve volume touches"
5 files changed, 131 insertions, 39 deletions
diff --git a/packages/SystemUI/res/layout/volume_dialog.xml b/packages/SystemUI/res/layout/volume_dialog.xml index 117cd14f4463..53dff05b74ef 100644 --- a/packages/SystemUI/res/layout/volume_dialog.xml +++ b/packages/SystemUI/res/layout/volume_dialog.xml @@ -59,6 +59,7 @@ android:gravity="center" android:layout_gravity="end" android:translationZ="8dp" + android:clickable="true" android:orientation="vertical" > <TextView @@ -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" /> diff --git a/packages/SystemUI/res/layout/volume_dialog_row.xml b/packages/SystemUI/res/layout/volume_dialog_row.xml index 3e80085225e2..a9e5adfa531a 100644 --- a/packages/SystemUI/res/layout/volume_dialog_row.xml +++ b/packages/SystemUI/res/layout/volume_dialog_row.xml @@ -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" /> @@ -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 @@ -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> @@ -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 diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java index 001a582297af..0c6e0f694b49 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java @@ -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; @@ -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; @@ -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<>(); @@ -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, @@ -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) { @@ -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) { @@ -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) { @@ -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(); } diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeUiLayout.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeUiLayout.java index 368194e57b9d..f50a28766d70 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeUiLayout.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeUiLayout.java @@ -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(); 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 2d28c9f214fb..4888fb284a35 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.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; @@ -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) { @@ -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); + } } |