diff options
5 files changed, 75 insertions, 6 deletions
diff --git a/services/core/java/com/android/server/vibrator/HalVibration.java b/services/core/java/com/android/server/vibrator/HalVibration.java index 743d02d100b1..70e2e27a3bae 100644 --- a/services/core/java/com/android/server/vibrator/HalVibration.java +++ b/services/core/java/com/android/server/vibrator/HalVibration.java @@ -102,6 +102,23 @@ final class HalVibration extends Vibration { } /** + * Resolves the default vibration amplitude of {@link #getEffectToPlay()} and each fallback. + * + * @param defaultAmplitude An integer in [1,255] representing the device default amplitude to + * replace the {@link VibrationEffect#DEFAULT_AMPLITUDE}. + */ + public void resolveEffects(int defaultAmplitude) { + CombinedVibration newEffect = + mEffectToPlay.transform(VibrationEffect::resolve, defaultAmplitude); + if (!Objects.equals(mEffectToPlay, newEffect)) { + mEffectToPlay = newEffect; + } + for (int i = 0; i < mFallbacks.size(); i++) { + mFallbacks.setValueAt(i, mFallbacks.valueAt(i).resolve(defaultAmplitude)); + } + } + + /** * Scales the {@link #getEffectToPlay()} and each fallback effect with a scaling transformation. * * @param scaler A {@link VibrationEffect.Transformation<Integer>} that takes one of the diff --git a/services/core/java/com/android/server/vibrator/VibrationScaler.java b/services/core/java/com/android/server/vibrator/VibrationScaler.java index 09a177a6951b..7163319f281a 100644 --- a/services/core/java/com/android/server/vibrator/VibrationScaler.java +++ b/services/core/java/com/android/server/vibrator/VibrationScaler.java @@ -73,6 +73,13 @@ final class VibrationScaler { } /** + * Returns the default vibration amplitude configured for this device, value in [1,255]. + */ + public int getDefaultVibrationAmplitude() { + return mDefaultVibrationAmplitude; + } + + /** * Calculates the scale to be applied to external vibration with given usage. * * @param usageHint one of VibrationAttributes.USAGE_* diff --git a/services/core/java/com/android/server/vibrator/VibrationStepConductor.java b/services/core/java/com/android/server/vibrator/VibrationStepConductor.java index 9cf942e91439..f6af9ad991ff 100644 --- a/services/core/java/com/android/server/vibrator/VibrationStepConductor.java +++ b/services/core/java/com/android/server/vibrator/VibrationStepConductor.java @@ -160,7 +160,10 @@ final class VibrationStepConductor implements IBinder.DeathRecipient { if (Flags.adaptiveHapticsEnabled()) { waitForVibrationParamsIfRequired(); } + // Scale resolves the default amplitudes from the effect before scaling them. mVibration.scaleEffects(mVibrationScaler::scale); + } else { + mVibration.resolveEffects(mVibrationScaler.getDefaultVibrationAmplitude()); } mVibration.adaptToDevice(mDeviceAdapter); diff --git a/services/core/java/com/android/server/vibrator/VibratorManagerService.java b/services/core/java/com/android/server/vibrator/VibratorManagerService.java index d979c6112cf5..be5d15877e32 100644 --- a/services/core/java/com/android/server/vibrator/VibratorManagerService.java +++ b/services/core/java/com/android/server/vibrator/VibratorManagerService.java @@ -884,8 +884,10 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { private Vibration.EndInfo startVibrationOnInputDevicesLocked(HalVibration vib) { if (!vib.callerInfo.attrs.isFlagSet( VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_SCALE)) { - // Scale effect before dispatching it to the input devices. + // Scale resolves the default amplitudes from the effect before scaling them. vib.scaleEffects(mVibrationScaler::scale); + } else { + vib.resolveEffects(mVibrationScaler.getDefaultVibrationAmplitude()); } mInputDeviceDelegate.vibrateIfAvailable(vib.callerInfo, vib.getEffectToPlay()); diff --git a/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java b/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java index 7db707a42ff0..e7571ef47864 100644 --- a/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java +++ b/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java @@ -1421,6 +1421,7 @@ public class VibratorManagerServiceTest { public void vibrate_withIntensitySettings_appliesSettingsToScaleVibrations() throws Exception { int defaultNotificationIntensity = mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_NOTIFICATION); + // This will scale up notification vibrations. setUserSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY, defaultNotificationIntensity < Vibrator.VIBRATION_INTENSITY_HIGH ? defaultNotificationIntensity + 1 @@ -1428,6 +1429,7 @@ public class VibratorManagerServiceTest { int defaultTouchIntensity = mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_TOUCH); + // This will scale down touch vibrations. setUserSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, defaultTouchIntensity > Vibrator.VIBRATION_INTENSITY_LOW ? defaultTouchIntensity - 1 @@ -1482,6 +1484,42 @@ public class VibratorManagerServiceTest { } @Test + public void vibrate_withBypassScaleFlag_ignoresIntensitySettingsAndResolvesAmplitude() + throws Exception { + // Permission needed for bypassing user settings + grantPermission(android.Manifest.permission.MODIFY_PHONE_STATE); + + int defaultTouchIntensity = + mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_TOUCH); + // This will scale down touch vibrations. + setUserSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, + defaultTouchIntensity > Vibrator.VIBRATION_INTENSITY_LOW + ? defaultTouchIntensity - 1 + : defaultTouchIntensity); + + int defaultAmplitude = mContextSpy.getResources().getInteger( + com.android.internal.R.integer.config_defaultVibrationAmplitude); + + mockVibrators(1); + FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(1); + fakeVibrator.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL); + VibratorManagerService service = createSystemReadyService(); + + vibrateAndWaitUntilFinished(service, + VibrationEffect.createOneShot(100, VibrationEffect.DEFAULT_AMPLITUDE), + new VibrationAttributes.Builder() + .setUsage(VibrationAttributes.USAGE_TOUCH) + .setFlags(VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_SCALE) + .build()); + + assertEquals(1, fakeVibrator.getAllEffectSegments().size()); + + assertEquals(defaultAmplitude / 255f, fakeVibrator.getAmplitudes().get(0), 1e-5); + + cancelVibrate(service); // Clean up long-ish effect. + } + + @Test public void vibrate_withPowerModeChange_cancelVibrationIfNotAllowed() throws Exception { mockVibrators(1, 2); VibratorManagerService service = createSystemReadyService(); @@ -1879,6 +1917,9 @@ public class VibratorManagerServiceTest { @Test public void onExternalVibration_withBypassMuteAudioFlag_ignoresUserSettings() { + // Permission needed for bypassing user settings + grantPermission(android.Manifest.permission.MODIFY_PHONE_STATE); + mockVibrators(1); mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_EXTERNAL_CONTROL); setUserSetting(Settings.System.ALARM_VIBRATION_INTENSITY, @@ -1892,12 +1933,12 @@ public class VibratorManagerServiceTest { .build(); createSystemReadyService(); - int scale = mExternalVibratorService.onExternalVibrationStart( - new ExternalVibration(UID, PACKAGE_NAME, audioAttrs, - mock(IExternalVibrationController.class))); + ExternalVibration vib = new ExternalVibration(UID, PACKAGE_NAME, audioAttrs, + mock(IExternalVibrationController.class)); + int scale = mExternalVibratorService.onExternalVibrationStart(vib); assertEquals(IExternalVibratorService.SCALE_MUTE, scale); - createSystemReadyService(); + mExternalVibratorService.onExternalVibrationStop(vib); scale = mExternalVibratorService.onExternalVibrationStart( new ExternalVibration(UID, PACKAGE_NAME, flaggedAudioAttrs, mock(IExternalVibrationController.class))); @@ -1912,7 +1953,6 @@ public class VibratorManagerServiceTest { Vibrator.VIBRATION_INTENSITY_OFF); AudioAttributes flaggedAudioAttrs = new AudioAttributes.Builder() .setUsage(AudioAttributes.USAGE_UNKNOWN) - .setFlags(AudioAttributes.FLAG_BYPASS_MUTE) .build(); createSystemReadyService(); |