Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 84d6ca73 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Improve volume touches"

parents 5f2a4ef7 45d4ab07
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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" />
+3 −3
Original line number Diff line number Diff line
@@ -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
+11 −33
Original line number Diff line number Diff line
@@ -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();
        }
+6 −0
Original line number Diff line number Diff line
@@ -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();
+109 −2
Original line number Diff line number Diff line
@@ -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);
    }
}