Merge "Using View.performHapticFeedback on Volume Dialog Impl when the silent and vibrate-only icons are pressed" into udc-qpr-dev

This commit is contained in:
Juan Sebastian Martinez
2023-07-14 20:39:28 +00:00
committed by Android (Google) Code Review
3 changed files with 142 additions and 10 deletions

View File

@@ -34,6 +34,7 @@ import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import static com.android.internal.jank.InteractionJankMonitor.CUJ_VOLUME_CONTROL;
import static com.android.internal.jank.InteractionJankMonitor.Configuration.Builder;
import static com.android.systemui.flags.Flags.ONE_WAY_HAPTICS_API_MIGRATION;
import static com.android.systemui.volume.Events.DISMISS_REASON_POSTURE_CHANGED;
import static com.android.systemui.volume.Events.DISMISS_REASON_SETTINGS_CLICKED;
@@ -82,6 +83,7 @@ import android.util.Slog;
import android.util.SparseBooleanArray;
import android.view.ContextThemeWrapper;
import android.view.Gravity;
import android.view.HapticFeedbackConstants;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.AccessibilityDelegate;
@@ -120,6 +122,7 @@ import com.android.systemui.Dumpable;
import com.android.systemui.Prefs;
import com.android.systemui.R;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.media.dialog.MediaOutputDialogFactory;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.VolumeDialog;
@@ -300,6 +303,7 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
private final DevicePostureController mDevicePostureController;
private @DevicePostureController.DevicePostureInt int mDevicePosture;
private int mOrientation;
private final FeatureFlags mFeatureFlags;
public VolumeDialogImpl(
Context context,
@@ -315,7 +319,9 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
CsdWarningDialog.Factory csdWarningDialogFactory,
DevicePostureController devicePostureController,
Looper looper,
DumpManager dumpManager) {
DumpManager dumpManager,
FeatureFlags featureFlags) {
mFeatureFlags = featureFlags;
mContext =
new ContextThemeWrapper(context, R.style.volume_dialog_theme);
mHandler = new H(looper);
@@ -1319,12 +1325,14 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
private void provideTouchFeedbackH(int newRingerMode) {
VibrationEffect effect = null;
int hapticConstant = HapticFeedbackConstants.NO_HAPTICS;
switch (newRingerMode) {
case RINGER_MODE_NORMAL:
mController.scheduleTouchFeedback();
break;
case RINGER_MODE_SILENT:
effect = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
hapticConstant = HapticFeedbackConstants.TOGGLE_OFF;
break;
case RINGER_MODE_VIBRATE:
// Feedback handled by onStateChange, for feedback both when user toggles
@@ -1332,8 +1340,11 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
break;
default:
effect = VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK);
hapticConstant = HapticFeedbackConstants.TOGGLE_ON;
}
if (effect != null) {
if (mFeatureFlags.isEnabled(ONE_WAY_HAPTICS_API_MIGRATION)) {
mDialogView.performHapticFeedback(hapticConstant);
} else if (effect != null) {
mController.vibrate(effect);
}
}
@@ -1770,7 +1781,22 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
&& mState.ringerModeInternal != -1
&& mState.ringerModeInternal != state.ringerModeInternal
&& state.ringerModeInternal == AudioManager.RINGER_MODE_VIBRATE) {
mController.vibrate(VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK));
if (mFeatureFlags.isEnabled(ONE_WAY_HAPTICS_API_MIGRATION)) {
if (mShowing) {
// The dialog view is responsible for triggering haptics in the oneway API
mDialogView.performHapticFeedback(HapticFeedbackConstants.TOGGLE_ON);
}
/*
TODO(b/290642122): If the dialog is not showing, we have the case where haptics is
enabled by dragging the volume slider of Settings to a value of 0. This must be
handled by view Slices in Settings whilst using the performHapticFeedback API.
*/
} else {
// Old behavior only active if the oneway API is not used.
mController.vibrate(VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK));
}
}
mState = state;
mDynamic.clear();

View File

@@ -22,6 +22,7 @@ import android.os.Looper;
import com.android.internal.jank.InteractionJankMonitor;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.media.dialog.MediaOutputDialogFactory;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.VolumeDialog;
@@ -61,7 +62,8 @@ public interface VolumeModule {
InteractionJankMonitor interactionJankMonitor,
CsdWarningDialog.Factory csdFactory,
DevicePostureController devicePostureController,
DumpManager dumpManager) {
DumpManager dumpManager,
FeatureFlags featureFlags) {
VolumeDialogImpl impl = new VolumeDialogImpl(
context,
volumeDialogController,
@@ -76,7 +78,8 @@ public interface VolumeModule {
csdFactory,
devicePostureController,
Looper.getMainLooper(),
dumpManager);
dumpManager,
featureFlags);
impl.setStreamImportant(AudioManager.STREAM_SYSTEM, false);
impl.setAutomute(true);
impl.setSilentMode(false);

View File

@@ -16,6 +16,7 @@
package com.android.systemui.volume;
import static com.android.systemui.flags.Flags.ONE_WAY_HAPTICS_API_MIGRATION;
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;
@@ -51,6 +52,7 @@ import com.android.systemui.Prefs;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FakeFeatureFlags;
import com.android.systemui.media.dialog.MediaOutputDialogFactory;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.VolumeDialogController;
@@ -117,6 +119,8 @@ public class VolumeDialogImplTest extends SysuiTestCase {
}
};
private FakeFeatureFlags mFeatureFlags;
@Before
public void setup() throws Exception {
MockitoAnnotations.initMocks(this);
@@ -132,6 +136,8 @@ public class VolumeDialogImplTest extends SysuiTestCase {
mConfigurationController = new FakeConfigurationController();
mFeatureFlags = new FakeFeatureFlags();
mDialog = new VolumeDialogImpl(
getContext(),
mVolumeDialogController,
@@ -146,7 +152,8 @@ public class VolumeDialogImplTest extends SysuiTestCase {
mCsdWarningDialogFactory,
mPostureController,
mTestableLooper.getLooper(),
mDumpManager);
mDumpManager,
mFeatureFlags);
mDialog.init(0, null);
State state = createShellState();
mDialog.onStateChangedH(state);
@@ -254,6 +261,7 @@ public class VolumeDialogImplTest extends SysuiTestCase {
@Test
public void testVibrateOnRingerChangedToVibrate() {
mFeatureFlags.set(ONE_WAY_HAPTICS_API_MIGRATION, false);
final State initialSilentState = new State();
initialSilentState.ringerModeInternal = AudioManager.RINGER_MODE_SILENT;
@@ -273,8 +281,31 @@ public class VolumeDialogImplTest extends SysuiTestCase {
verify(mVolumeDialogController).vibrate(any());
}
@Test
public void testControllerDoesNotVibrateOnRingerChangedToVibrate_OnewayAPI_On() {
mFeatureFlags.set(ONE_WAY_HAPTICS_API_MIGRATION, true);
final State initialSilentState = new State();
initialSilentState.ringerModeInternal = AudioManager.RINGER_MODE_SILENT;
final State vibrateState = new State();
vibrateState.ringerModeInternal = AudioManager.RINGER_MODE_VIBRATE;
// change ringer to silent
mDialog.onStateChangedH(initialSilentState);
// expected: shouldn't call vibrate yet
verify(mVolumeDialogController, never()).vibrate(any());
// changed ringer to vibrate
mDialog.onStateChangedH(vibrateState);
// expected: vibrate method of controller is not used
verify(mVolumeDialogController, never()).vibrate(any());
}
@Test
public void testNoVibrateOnRingerInitialization() {
mFeatureFlags.set(ONE_WAY_HAPTICS_API_MIGRATION, false);
final State initialUnsetState = new State();
initialUnsetState.ringerModeInternal = -1;
@@ -291,8 +322,43 @@ public class VolumeDialogImplTest extends SysuiTestCase {
verify(mVolumeDialogController, never()).vibrate(any());
}
@Test
public void testControllerDoesNotVibrateOnRingerInitialization_OnewayAPI_On() {
mFeatureFlags.set(ONE_WAY_HAPTICS_API_MIGRATION, true);
final State initialUnsetState = new State();
initialUnsetState.ringerModeInternal = -1;
// ringer not initialized yet:
mDialog.onStateChangedH(initialUnsetState);
final State vibrateState = new State();
vibrateState.ringerModeInternal = AudioManager.RINGER_MODE_VIBRATE;
// changed ringer to vibrate
mDialog.onStateChangedH(vibrateState);
// shouldn't call vibrate on the controller either
verify(mVolumeDialogController, never()).vibrate(any());
}
@Test
public void testSelectVibrateFromDrawer() {
mFeatureFlags.set(ONE_WAY_HAPTICS_API_MIGRATION, false);
final State initialUnsetState = new State();
initialUnsetState.ringerModeInternal = AudioManager.RINGER_MODE_NORMAL;
mDialog.onStateChangedH(initialUnsetState);
mActiveRinger.performClick();
mDrawerVibrate.performClick();
// Make sure we've actually changed the ringer mode.
verify(mVolumeDialogController, times(1)).setRingerMode(
AudioManager.RINGER_MODE_VIBRATE, false);
}
@Test
public void testSelectVibrateFromDrawer_OnewayAPI_On() {
mFeatureFlags.set(ONE_WAY_HAPTICS_API_MIGRATION, true);
final State initialUnsetState = new State();
initialUnsetState.ringerModeInternal = AudioManager.RINGER_MODE_NORMAL;
mDialog.onStateChangedH(initialUnsetState);
@@ -307,6 +373,22 @@ public class VolumeDialogImplTest extends SysuiTestCase {
@Test
public void testSelectMuteFromDrawer() {
mFeatureFlags.set(ONE_WAY_HAPTICS_API_MIGRATION, false);
final State initialUnsetState = new State();
initialUnsetState.ringerModeInternal = AudioManager.RINGER_MODE_NORMAL;
mDialog.onStateChangedH(initialUnsetState);
mActiveRinger.performClick();
mDrawerMute.performClick();
// Make sure we've actually changed the ringer mode.
verify(mVolumeDialogController, times(1)).setRingerMode(
AudioManager.RINGER_MODE_SILENT, false);
}
@Test
public void testSelectMuteFromDrawer_OnewayAPI_On() {
mFeatureFlags.set(ONE_WAY_HAPTICS_API_MIGRATION, true);
final State initialUnsetState = new State();
initialUnsetState.ringerModeInternal = AudioManager.RINGER_MODE_NORMAL;
mDialog.onStateChangedH(initialUnsetState);
@@ -321,6 +403,22 @@ public class VolumeDialogImplTest extends SysuiTestCase {
@Test
public void testSelectNormalFromDrawer() {
mFeatureFlags.set(ONE_WAY_HAPTICS_API_MIGRATION, false);
final State initialUnsetState = new State();
initialUnsetState.ringerModeInternal = AudioManager.RINGER_MODE_VIBRATE;
mDialog.onStateChangedH(initialUnsetState);
mActiveRinger.performClick();
mDrawerNormal.performClick();
// Make sure we've actually changed the ringer mode.
verify(mVolumeDialogController, times(1)).setRingerMode(
AudioManager.RINGER_MODE_NORMAL, false);
}
@Test
public void testSelectNormalFromDrawer_OnewayAPI_On() {
mFeatureFlags.set(ONE_WAY_HAPTICS_API_MIGRATION, true);
final State initialUnsetState = new State();
initialUnsetState.ringerModeInternal = AudioManager.RINGER_MODE_VIBRATE;
mDialog.onStateChangedH(initialUnsetState);
@@ -383,7 +481,8 @@ public class VolumeDialogImplTest extends SysuiTestCase {
mCsdWarningDialogFactory,
devicePostureController,
mTestableLooper.getLooper(),
mDumpManager
mDumpManager,
mFeatureFlags
);
dialog.init(0 , null);
@@ -423,7 +522,8 @@ public class VolumeDialogImplTest extends SysuiTestCase {
mCsdWarningDialogFactory,
devicePostureController,
mTestableLooper.getLooper(),
mDumpManager
mDumpManager,
mFeatureFlags
);
dialog.init(0, null);
@@ -462,7 +562,8 @@ public class VolumeDialogImplTest extends SysuiTestCase {
mCsdWarningDialogFactory,
devicePostureController,
mTestableLooper.getLooper(),
mDumpManager
mDumpManager,
mFeatureFlags
);
dialog.init(0, null);
@@ -503,7 +604,9 @@ public class VolumeDialogImplTest extends SysuiTestCase {
mCsdWarningDialogFactory,
mPostureController,
mTestableLooper.getLooper(),
mDumpManager);
mDumpManager,
mFeatureFlags
);
dialog.init(0, null);
verify(mPostureController, never()).removeCallback(any());