Loading services/core/java/com/android/server/vibrator/HalVibration.java +17 −0 Original line number Diff line number Diff line Loading @@ -101,6 +101,23 @@ final class HalVibration extends Vibration { mFallbacks.put(effectId, effect); } /** * 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. * Loading services/core/java/com/android/server/vibrator/VibrationScaler.java +7 −0 Original line number Diff line number Diff line Loading @@ -72,6 +72,13 @@ final class VibrationScaler { mScaleLevels.put(SCALE_VERY_HIGH, new ScaleLevel(SCALE_FACTOR_VERY_HIGH)); } /** * 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. * Loading services/core/java/com/android/server/vibrator/VibrationStepConductor.java +3 −0 Original line number Diff line number Diff line Loading @@ -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); Loading services/core/java/com/android/server/vibrator/VibratorManagerService.java +3 −1 Original line number Diff line number Diff line Loading @@ -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()); Loading services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java +45 −5 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading Loading @@ -1481,6 +1483,42 @@ public class VibratorManagerServiceTest { cancelVibrate(service); // Clean up long-ish effect. } @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); Loading Loading @@ -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, Loading @@ -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))); Loading @@ -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(); Loading Loading
services/core/java/com/android/server/vibrator/HalVibration.java +17 −0 Original line number Diff line number Diff line Loading @@ -101,6 +101,23 @@ final class HalVibration extends Vibration { mFallbacks.put(effectId, effect); } /** * 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. * Loading
services/core/java/com/android/server/vibrator/VibrationScaler.java +7 −0 Original line number Diff line number Diff line Loading @@ -72,6 +72,13 @@ final class VibrationScaler { mScaleLevels.put(SCALE_VERY_HIGH, new ScaleLevel(SCALE_FACTOR_VERY_HIGH)); } /** * 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. * Loading
services/core/java/com/android/server/vibrator/VibrationStepConductor.java +3 −0 Original line number Diff line number Diff line Loading @@ -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); Loading
services/core/java/com/android/server/vibrator/VibratorManagerService.java +3 −1 Original line number Diff line number Diff line Loading @@ -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()); Loading
services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java +45 −5 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading Loading @@ -1481,6 +1483,42 @@ public class VibratorManagerServiceTest { cancelVibrate(service); // Clean up long-ish effect. } @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); Loading Loading @@ -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, Loading @@ -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))); Loading @@ -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(); Loading