Add flag to refresh of user vibration settings before vibrating
Add hidden flag to VibrationAttributes that enforces the service to refresh the cached user settings values before vibrating with the given effect. This allows user settings to apply this to vibratins played as preview of new intensities set by the slider. This solution still requires the Settings to update the user intensity before playing the preview, but it doesn't bypass any user settings or policies in order to play the preview, avoiding a shortcut that could be used to enforce vibrations without user control. This setting is also applied to external vibrations, which could be used to preview haptics instead if a prebaked effect. It also applies to ringer mode, that is now cached by the service instead of queried on each vibrate call. Fix: 219693646 Fix: 219695212 Fix: 157533521 Test: VibrationSettingsTest & VibratorManagerServiceTest Change-Id: I605ccd2a4a3b89f1ba5bc86d8f3f64dd6d2714eb
This commit is contained in:
@@ -166,12 +166,28 @@ public final class VibrationAttributes implements Parcelable {
|
||||
*/
|
||||
public static final int FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF = 0x2;
|
||||
|
||||
/**
|
||||
* Flag requesting vibration effect to be played with fresh user settings values.
|
||||
*
|
||||
* <p>This flag is not protected by any permission, but vibrations that use it require an extra
|
||||
* query of user vibration intensity settings, ringer mode and other controls that affect the
|
||||
* vibration effect playback, which can increase the latency for the overall request.
|
||||
*
|
||||
* <p>This is intended to be used on scenarios where the user settings might have changed
|
||||
* recently, and needs to be applied to this vibration, like settings controllers that preview
|
||||
* newly set intensities to the user.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final int FLAG_INVALIDATE_SETTINGS_CACHE = 0x3;
|
||||
|
||||
/**
|
||||
* All flags supported by vibrator service, update it when adding new flag.
|
||||
* @hide
|
||||
*/
|
||||
public static final int FLAG_ALL_SUPPORTED =
|
||||
FLAG_BYPASS_INTERRUPTION_POLICY | FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF;
|
||||
FLAG_BYPASS_INTERRUPTION_POLICY | FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF
|
||||
| FLAG_INVALIDATE_SETTINGS_CACHE;
|
||||
|
||||
/** Creates a new {@link VibrationAttributes} instance with given usage. */
|
||||
public static @NonNull VibrationAttributes createForUsage(@Usage int usage) {
|
||||
@@ -446,8 +462,10 @@ public final class VibrationAttributes implements Parcelable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set flags
|
||||
* @param flags combination of flags to be set.
|
||||
* Sets only the flags specified in the bitmask, leaving the other supported flag values
|
||||
* unchanged in the builder.
|
||||
*
|
||||
* @param flags Combination of flags to be set.
|
||||
* @param mask Bit range that should be changed.
|
||||
* @return the same Builder instance.
|
||||
*/
|
||||
@@ -456,5 +474,18 @@ public final class VibrationAttributes implements Parcelable {
|
||||
mFlags = (mFlags & ~mask) | (flags & mask);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set all supported flags with given combination of flags, overriding any previous values
|
||||
* set to this builder.
|
||||
*
|
||||
* @param flags combination of flags to be set.
|
||||
* @return the same Builder instance.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public @NonNull Builder setFlags(@Flag int flags) {
|
||||
return setFlags(flags, FLAG_ALL_SUPPORTED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5446,8 +5446,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
VibrationAttributes attrs = getVibrationAttributes(effectId);
|
||||
if (always) {
|
||||
attrs = new VibrationAttributes.Builder(attrs)
|
||||
.setFlags(VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF,
|
||||
VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF)
|
||||
.setFlags(VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF)
|
||||
.build();
|
||||
}
|
||||
mVibrator.vibrate(uid, packageName, effect, reason, attrs);
|
||||
|
||||
@@ -121,6 +121,11 @@ final class VibrationSettings {
|
||||
USAGE_PHYSICAL_EMULATION,
|
||||
USAGE_HARDWARE_FEEDBACK));
|
||||
|
||||
private static final IntentFilter USER_SWITCHED_INTENT_FILTER =
|
||||
new IntentFilter(Intent.ACTION_USER_SWITCHED);
|
||||
private static final IntentFilter INTERNAL_RINGER_MODE_CHANGED_INTENT_FILTER =
|
||||
new IntentFilter(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION);
|
||||
|
||||
/** Listener for changes on vibration settings. */
|
||||
interface OnVibratorSettingsChanged {
|
||||
/** Callback triggered when any of the vibrator settings change. */
|
||||
@@ -130,11 +135,11 @@ final class VibrationSettings {
|
||||
private final Object mLock = new Object();
|
||||
private final Context mContext;
|
||||
private final String mSystemUiPackage;
|
||||
private final SettingsObserver mSettingObserver;
|
||||
private final SettingsContentObserver mSettingObserver;
|
||||
@VisibleForTesting
|
||||
final UidObserver mUidObserver;
|
||||
@VisibleForTesting
|
||||
final UserObserver mUserReceiver;
|
||||
final SettingsBroadcastReceiver mSettingChangeReceiver;
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private final List<OnVibratorSettingsChanged> mListeners = new ArrayList<>();
|
||||
@@ -154,6 +159,8 @@ final class VibrationSettings {
|
||||
private boolean mBatterySaverMode;
|
||||
@GuardedBy("mLock")
|
||||
private boolean mVibrateOn;
|
||||
@GuardedBy("mLock")
|
||||
private int mRingerMode;
|
||||
|
||||
VibrationSettings(Context context, Handler handler) {
|
||||
this(context, handler, new VibrationConfig(context.getResources()));
|
||||
@@ -163,9 +170,9 @@ final class VibrationSettings {
|
||||
VibrationSettings(Context context, Handler handler, VibrationConfig config) {
|
||||
mContext = context;
|
||||
mVibrationConfig = config;
|
||||
mSettingObserver = new SettingsObserver(handler);
|
||||
mSettingObserver = new SettingsContentObserver(handler);
|
||||
mUidObserver = new UidObserver();
|
||||
mUserReceiver = new UserObserver();
|
||||
mSettingChangeReceiver = new SettingsBroadcastReceiver();
|
||||
|
||||
mSystemUiPackage = LocalServices.getService(PackageManagerInternal.class)
|
||||
.getSystemUiServiceComponent().getPackageName();
|
||||
@@ -188,12 +195,13 @@ final class VibrationSettings {
|
||||
VibrationEffect.get(VibrationEffect.EFFECT_TICK, false));
|
||||
|
||||
// Update with current values from settings.
|
||||
updateSettings();
|
||||
update();
|
||||
}
|
||||
|
||||
public void onSystemReady() {
|
||||
synchronized (mLock) {
|
||||
mAudioManager = mContext.getSystemService(AudioManager.class);
|
||||
mRingerMode = mAudioManager.getRingerModeInternal();
|
||||
}
|
||||
try {
|
||||
ActivityManager.getService().registerUidObserver(mUidObserver,
|
||||
@@ -224,8 +232,8 @@ final class VibrationSettings {
|
||||
}
|
||||
});
|
||||
|
||||
IntentFilter filter = new IntentFilter(Intent.ACTION_USER_SWITCHED);
|
||||
mContext.registerReceiver(mUserReceiver, filter, Context.RECEIVER_NOT_EXPORTED);
|
||||
registerSettingsChangeReceiver(USER_SWITCHED_INTENT_FILTER);
|
||||
registerSettingsChangeReceiver(INTERNAL_RINGER_MODE_CHANGED_INTENT_FILTER);
|
||||
|
||||
// Listen to all settings that might affect the result of Vibrator.getVibrationIntensity.
|
||||
registerSettingsObserver(Settings.System.getUriFor(Settings.System.VIBRATE_INPUT_DEVICES));
|
||||
@@ -248,7 +256,7 @@ final class VibrationSettings {
|
||||
Settings.System.getUriFor(Settings.System.RING_VIBRATION_INTENSITY));
|
||||
|
||||
// Update with newly loaded services.
|
||||
updateSettings();
|
||||
update();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -396,16 +404,17 @@ final class VibrationSettings {
|
||||
// Only ringtone and notification vibrations are disabled when phone is on silent mode.
|
||||
return true;
|
||||
}
|
||||
// If audio manager was not loaded yet then assume most restrictive mode.
|
||||
int ringerMode = (mAudioManager == null)
|
||||
? AudioManager.RINGER_MODE_SILENT
|
||||
: mAudioManager.getRingerModeInternal();
|
||||
return ringerMode != AudioManager.RINGER_MODE_SILENT;
|
||||
return mRingerMode != AudioManager.RINGER_MODE_SILENT;
|
||||
}
|
||||
|
||||
/** Updates all vibration settings and triggers registered listeners. */
|
||||
@VisibleForTesting
|
||||
void updateSettings() {
|
||||
/** Update all cached settings and triggers registered listeners. */
|
||||
void update() {
|
||||
updateSettings();
|
||||
updateRingerMode();
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
private void updateSettings() {
|
||||
synchronized (mLock) {
|
||||
mVibrateInputDevices = loadSystemSetting(Settings.System.VIBRATE_INPUT_DEVICES, 0) > 0;
|
||||
mVibrateOn = loadSystemSetting(Settings.System.VIBRATE_ON, 1) > 0;
|
||||
@@ -435,7 +444,6 @@ final class VibrationSettings {
|
||||
loadSystemSetting(Settings.System.RING_VIBRATION_INTENSITY, -1),
|
||||
getDefaultIntensity(USAGE_RINGTONE));
|
||||
|
||||
|
||||
mCurrentVibrationIntensities.clear();
|
||||
mCurrentVibrationIntensities.put(USAGE_ALARM, alarmIntensity);
|
||||
mCurrentVibrationIntensities.put(USAGE_NOTIFICATION, notificationIntensity);
|
||||
@@ -469,7 +477,16 @@ final class VibrationSettings {
|
||||
// A11y is not disabled by any haptic feedback setting.
|
||||
mCurrentVibrationIntensities.put(USAGE_ACCESSIBILITY, positiveHapticFeedbackIntensity);
|
||||
}
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
private void updateRingerMode() {
|
||||
synchronized (mLock) {
|
||||
// If audio manager was not loaded yet then assume most restrictive mode.
|
||||
// This will be loaded again as soon as the audio manager is loaded in onSystemReady.
|
||||
mRingerMode = (mAudioManager == null)
|
||||
? AudioManager.RINGER_MODE_SILENT
|
||||
: mAudioManager.getRingerModeInternal();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -586,6 +603,11 @@ final class VibrationSettings {
|
||||
UserHandle.USER_ALL);
|
||||
}
|
||||
|
||||
private void registerSettingsChangeReceiver(IntentFilter intentFilter) {
|
||||
mContext.registerReceiver(mSettingChangeReceiver, intentFilter,
|
||||
Context.RECEIVER_NOT_EXPORTED);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private VibrationEffect createEffectFromResource(int resId) {
|
||||
long[] timings = getLongIntArray(mContext.getResources(), resId);
|
||||
@@ -616,24 +638,33 @@ final class VibrationSettings {
|
||||
}
|
||||
|
||||
/** Implementation of {@link ContentObserver} to be registered to a setting {@link Uri}. */
|
||||
private final class SettingsObserver extends ContentObserver {
|
||||
SettingsObserver(Handler handler) {
|
||||
private final class SettingsContentObserver extends ContentObserver {
|
||||
SettingsContentObserver(Handler handler) {
|
||||
super(handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChange(boolean selfChange) {
|
||||
updateSettings();
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
/** Implementation of {@link BroadcastReceiver} to update settings on current user change. */
|
||||
/**
|
||||
* Implementation of {@link BroadcastReceiver} to update settings on current user or ringer
|
||||
* mode change.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
final class UserObserver extends BroadcastReceiver {
|
||||
final class SettingsBroadcastReceiver extends BroadcastReceiver {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) {
|
||||
updateSettings();
|
||||
String action = intent.getAction();
|
||||
if (Intent.ACTION_USER_SWITCHED.equals(action)) {
|
||||
// Reload all settings, as they are user-based.
|
||||
update();
|
||||
} else if (AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION.equals(action)) {
|
||||
updateRingerMode();
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -401,6 +401,12 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
uid, opPkg, reason);
|
||||
fillVibrationFallbacks(vib, effect);
|
||||
|
||||
if (attrs.isFlagSet(VibrationAttributes.FLAG_INVALIDATE_SETTINGS_CACHE)) {
|
||||
// Force update of user settings before checking if this vibration effect should
|
||||
// be ignored or scaled.
|
||||
mVibrationSettings.update();
|
||||
}
|
||||
|
||||
synchronized (mLock) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Starting vibrate for vibration " + vib.id);
|
||||
@@ -1506,12 +1512,20 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
return IExternalVibratorService.SCALE_MUTE;
|
||||
}
|
||||
|
||||
VibrationAttributes attrs = fixupVibrationAttributes(vib.getVibrationAttributes(),
|
||||
/* effect= */ null);
|
||||
if (attrs.isFlagSet(VibrationAttributes.FLAG_INVALIDATE_SETTINGS_CACHE)) {
|
||||
// Force update of user settings before checking if this vibration effect should
|
||||
// be ignored or scaled.
|
||||
mVibrationSettings.update();
|
||||
}
|
||||
|
||||
boolean alreadyUnderExternalControl = false;
|
||||
boolean waitForCompletion = false;
|
||||
int scale;
|
||||
synchronized (mLock) {
|
||||
Vibration.Status ignoreStatus = shouldIgnoreVibrationLocked(
|
||||
vib.getUid(), vib.getPackage(), vib.getVibrationAttributes());
|
||||
vib.getUid(), vib.getPackage(), attrs);
|
||||
if (ignoreStatus != null) {
|
||||
ExternalVibrationHolder vibHolder = new ExternalVibrationHolder(vib);
|
||||
vibHolder.scale = IExternalVibratorService.SCALE_MUTE;
|
||||
@@ -1549,7 +1563,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
mCurrentExternalVibration = new ExternalVibrationHolder(vib);
|
||||
vib.linkToDeath(mCurrentExternalVibration);
|
||||
mCurrentExternalVibration.scale = mVibrationScaler.getExternalVibrationScale(
|
||||
vib.getVibrationAttributes().getUsage());
|
||||
attrs.getUsage());
|
||||
scale = mCurrentExternalVibration.scale;
|
||||
}
|
||||
|
||||
@@ -1908,7 +1922,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
final int flags =
|
||||
commonOptions.force ? VibrationAttributes.FLAG_BYPASS_INTERRUPTION_POLICY : 0;
|
||||
return new VibrationAttributes.Builder()
|
||||
.setFlags(flags, VibrationAttributes.FLAG_ALL_SUPPORTED)
|
||||
.setFlags(flags)
|
||||
// Used to apply Settings.System.HAPTIC_FEEDBACK_INTENSITY to scale effects.
|
||||
.setUsage(VibrationAttributes.USAGE_TOUCH)
|
||||
.build();
|
||||
|
||||
@@ -277,6 +277,6 @@ public class VibrationScalerTest {
|
||||
Settings.System.putIntForUser(
|
||||
mContextSpy.getContentResolver(), settingName, value, UserHandle.USER_CURRENT);
|
||||
// FakeSettingsProvider don't support testing triggering ContentObserver yet.
|
||||
mVibrationSettings.updateSettings();
|
||||
mVibrationSettings.update();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -475,6 +475,24 @@ public class VibrationSettingsTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldIgnoreVibration_updateTriggeredAfterInternalRingerModeChanged() {
|
||||
// Vibrating settings on are overruled by ringer mode.
|
||||
setUserSetting(Settings.System.HAPTIC_FEEDBACK_ENABLED, 1);
|
||||
setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 1);
|
||||
setUserSetting(Settings.System.APPLY_RAMPING_RINGER, 1);
|
||||
setRingerMode(AudioManager.RINGER_MODE_NORMAL);
|
||||
|
||||
assertVibrationNotIgnoredForUsage(USAGE_RINGTONE);
|
||||
|
||||
// Testing the broadcast flow manually.
|
||||
mAudioManager.setRingerModeInternal(AudioManager.RINGER_MODE_SILENT);
|
||||
mVibrationSettings.mSettingChangeReceiver.onReceive(mContextSpy,
|
||||
new Intent(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION));
|
||||
|
||||
assertVibrationIgnoredForUsage(USAGE_RINGTONE, Vibration.Status.IGNORED_FOR_RINGER_MODE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldVibrateInputDevices_returnsSettingsValue() {
|
||||
setUserSetting(Settings.System.VIBRATE_INPUT_DEVICES, 1);
|
||||
@@ -577,7 +595,7 @@ public class VibrationSettingsTest {
|
||||
Settings.System.putIntForUser(mContextSpy.getContentResolver(),
|
||||
Settings.System.RING_VIBRATION_INTENSITY, VIBRATION_INTENSITY_LOW,
|
||||
UserHandle.USER_CURRENT);
|
||||
mVibrationSettings.mUserReceiver.onReceive(mContextSpy,
|
||||
mVibrationSettings.mSettingChangeReceiver.onReceive(mContextSpy,
|
||||
new Intent(Intent.ACTION_USER_SWITCHED));
|
||||
assertEquals(VIBRATION_INTENSITY_LOW,
|
||||
mVibrationSettings.getCurrentIntensity(USAGE_RINGTONE));
|
||||
@@ -587,7 +605,7 @@ public class VibrationSettingsTest {
|
||||
public void getCurrentIntensity_noHardwareFeedbackValueUsesHapticFeedbackValue() {
|
||||
setDefaultIntensity(USAGE_HARDWARE_FEEDBACK, VIBRATION_INTENSITY_MEDIUM);
|
||||
setUserSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, VIBRATION_INTENSITY_OFF);
|
||||
mVibrationSettings.updateSettings();
|
||||
mVibrationSettings.update();
|
||||
assertEquals(VIBRATION_INTENSITY_OFF, mVibrationSettings.getCurrentIntensity(USAGE_TOUCH));
|
||||
// If haptic feedback is off, fallback to default value.
|
||||
assertEquals(VIBRATION_INTENSITY_MEDIUM,
|
||||
@@ -596,7 +614,7 @@ public class VibrationSettingsTest {
|
||||
mVibrationSettings.getCurrentIntensity(USAGE_PHYSICAL_EMULATION));
|
||||
|
||||
setUserSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, VIBRATION_INTENSITY_HIGH);
|
||||
mVibrationSettings.updateSettings();
|
||||
mVibrationSettings.update();
|
||||
assertEquals(VIBRATION_INTENSITY_HIGH,
|
||||
mVibrationSettings.getCurrentIntensity(USAGE_TOUCH));
|
||||
// If haptic feedback is on, fallback to that value.
|
||||
@@ -633,7 +651,7 @@ public class VibrationSettingsTest {
|
||||
mVibrationSettings.shouldIgnoreVibration(UID,
|
||||
new VibrationAttributes.Builder()
|
||||
.setUsage(usage)
|
||||
.setFlags(flags, VibrationAttributes.FLAG_ALL_SUPPORTED)
|
||||
.setFlags(flags)
|
||||
.build()));
|
||||
}
|
||||
|
||||
@@ -654,18 +672,19 @@ public class VibrationSettingsTest {
|
||||
Settings.System.putStringForUser(
|
||||
mContextSpy.getContentResolver(), settingName, null, UserHandle.USER_CURRENT);
|
||||
// FakeSettingsProvider doesn't support testing triggering ContentObserver yet.
|
||||
mVibrationSettings.updateSettings();
|
||||
mVibrationSettings.update();
|
||||
}
|
||||
|
||||
private void setUserSetting(String settingName, int value) {
|
||||
Settings.System.putIntForUser(
|
||||
mContextSpy.getContentResolver(), settingName, value, UserHandle.USER_CURRENT);
|
||||
// FakeSettingsProvider doesn't support testing triggering ContentObserver yet.
|
||||
mVibrationSettings.updateSettings();
|
||||
mVibrationSettings.update();
|
||||
}
|
||||
|
||||
private void setRingerMode(int ringerMode) {
|
||||
mAudioManager.setRingerModeInternal(ringerMode);
|
||||
assertEquals(ringerMode, mAudioManager.getRingerModeInternal());
|
||||
mVibrationSettings.update();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -672,6 +672,42 @@ public class VibratorManagerServiceTest {
|
||||
eq(AudioAttributes.USAGE_UNKNOWN), anyInt(), anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void vibrate_withVibrationAttributesEnforceFreshSettings_refreshesVibrationSettings()
|
||||
throws Exception {
|
||||
mockVibrators(0);
|
||||
mVibratorProviders.get(0).setSupportedEffects(VibrationEffect.EFFECT_CLICK,
|
||||
VibrationEffect.EFFECT_TICK);
|
||||
setUserSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
|
||||
Vibrator.VIBRATION_INTENSITY_HIGH);
|
||||
VibratorManagerService service = createSystemReadyService();
|
||||
|
||||
VibrationAttributes enforceFreshAttrs = new VibrationAttributes.Builder()
|
||||
.setUsage(VibrationAttributes.USAGE_NOTIFICATION)
|
||||
.setFlags(VibrationAttributes.FLAG_INVALIDATE_SETTINGS_CACHE)
|
||||
.build();
|
||||
|
||||
setUserSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
|
||||
Vibrator.VIBRATION_INTENSITY_LOW);
|
||||
vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK), NOTIFICATION_ATTRS);
|
||||
// VibrationThread will start this vibration async, so wait before vibrating a second time.
|
||||
assertTrue(waitUntil(s -> mVibratorProviders.get(0).getAllEffectSegments().size() > 0,
|
||||
service, TEST_TIMEOUT_MILLIS));
|
||||
|
||||
vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_TICK), enforceFreshAttrs);
|
||||
// VibrationThread will start this vibration async, so wait before checking.
|
||||
assertTrue(waitUntil(s -> mVibratorProviders.get(0).getAllEffectSegments().size() > 1,
|
||||
service, TEST_TIMEOUT_MILLIS));
|
||||
|
||||
assertEquals(
|
||||
Arrays.asList(
|
||||
expectedPrebaked(VibrationEffect.EFFECT_CLICK,
|
||||
VibrationEffect.EFFECT_STRENGTH_STRONG),
|
||||
expectedPrebaked(VibrationEffect.EFFECT_TICK,
|
||||
VibrationEffect.EFFECT_STRENGTH_LIGHT)),
|
||||
mVibratorProviders.get(0).getAllEffectSegments());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void vibrate_withAttributesUnknownUsage_usesEffectToIdentifyTouchUsage() {
|
||||
VibratorManagerService service = createSystemReadyService();
|
||||
@@ -1280,7 +1316,11 @@ public class VibratorManagerServiceTest {
|
||||
}
|
||||
|
||||
private VibrationEffectSegment expectedPrebaked(int effectId) {
|
||||
return new PrebakedSegment(effectId, false, VibrationEffect.EFFECT_STRENGTH_MEDIUM);
|
||||
return expectedPrebaked(effectId, VibrationEffect.EFFECT_STRENGTH_MEDIUM);
|
||||
}
|
||||
|
||||
private VibrationEffectSegment expectedPrebaked(int effectId, int effectStrength) {
|
||||
return new PrebakedSegment(effectId, false, effectStrength);
|
||||
}
|
||||
|
||||
private void mockCapabilities(long... capabilities) {
|
||||
|
||||
Reference in New Issue
Block a user