Loading core/java/android/view/HapticFeedbackConstants.java +17 −5 Original line number Diff line number Diff line Loading @@ -83,11 +83,7 @@ public class HapticFeedbackConstants { */ public static final int TEXT_HANDLE_MOVE = 9; /** * The user unlocked the device * @hide */ public static final int ENTRY_BUMP = 10; // REMOVED: ENTRY_BUMP = 10 /** * The user has moved the dragged object within a droppable area. Loading Loading @@ -229,6 +225,22 @@ public class HapticFeedbackConstants { */ public static final int LONG_PRESS_POWER_BUTTON = 10003; /** * A haptic effect to signal the confirmation of a user biometric authentication * (e.g. fingerprint reading). * This is a private constant to be used only by system apps. * @hide */ public static final int BIOMETRIC_CONFIRM = 10004; /** * A haptic effect to signal the rejection of a user biometric authentication attempt * (e.g. fingerprint reading). * This is a private constant to be used only by system apps. * @hide */ public static final int BIOMETRIC_REJECT = 10005; /** * Flag for {@link View#performHapticFeedback(int, int) * View.performHapticFeedback(int, int)}: Ignore the setting in the Loading core/res/AndroidManifest.xml +7 −0 Original line number Diff line number Diff line Loading @@ -2593,6 +2593,13 @@ <permission android:name="android.permission.VIBRATE_ALWAYS_ON" android:protectionLevel="signature" /> <!-- Allows access to system-only haptic feedback constants. <p>Protection level: signature @hide --> <permission android:name="android.permission.VIBRATE_SYSTEM_CONSTANTS" android:protectionLevel="signature" /> <!-- @SystemApi Allows access to the vibrator state. <p>Protection level: signature @hide Loading services/core/java/com/android/server/vibrator/HapticFeedbackVibrationProvider.java +25 −1 Original line number Diff line number Diff line Loading @@ -44,6 +44,8 @@ public final class HapticFeedbackVibrationProvider { VibrationAttributes.createForUsage(VibrationAttributes.USAGE_PHYSICAL_EMULATION); private static final VibrationAttributes HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES = VibrationAttributes.createForUsage(VibrationAttributes.USAGE_HARDWARE_FEEDBACK); private static final VibrationAttributes COMMUNICATION_REQUEST_VIBRATION_ATTRIBUTES = VibrationAttributes.createForUsage(VibrationAttributes.USAGE_COMMUNICATION_REQUEST); private final VibratorInfo mVibratorInfo; private final boolean mHapticTextHandleEnabled; Loading Loading @@ -120,7 +122,6 @@ public final class HapticFeedbackVibrationProvider { return getKeyboardVibration(effectId); case HapticFeedbackConstants.VIRTUAL_KEY_RELEASE: case HapticFeedbackConstants.ENTRY_BUMP: case HapticFeedbackConstants.DRAG_CROSSING: return getVibration( effectId, Loading @@ -131,6 +132,7 @@ public final class HapticFeedbackVibrationProvider { case HapticFeedbackConstants.EDGE_RELEASE: case HapticFeedbackConstants.CALENDAR_DATE: case HapticFeedbackConstants.CONFIRM: case HapticFeedbackConstants.BIOMETRIC_CONFIRM: case HapticFeedbackConstants.GESTURE_START: case HapticFeedbackConstants.SCROLL_ITEM_FOCUS: case HapticFeedbackConstants.SCROLL_LIMIT: Loading @@ -143,6 +145,7 @@ public final class HapticFeedbackVibrationProvider { return getVibration(effectId, VibrationEffect.EFFECT_HEAVY_CLICK); case HapticFeedbackConstants.REJECT: case HapticFeedbackConstants.BIOMETRIC_REJECT: return getVibration(effectId, VibrationEffect.EFFECT_DOUBLE_CLICK); case HapticFeedbackConstants.SAFE_MODE_ENABLED: Loading Loading @@ -207,6 +210,10 @@ public final class HapticFeedbackVibrationProvider { case HapticFeedbackConstants.KEYBOARD_RELEASE: attrs = createKeyboardVibrationAttributes(fromIme); break; case HapticFeedbackConstants.BIOMETRIC_CONFIRM: case HapticFeedbackConstants.BIOMETRIC_REJECT: attrs = COMMUNICATION_REQUEST_VIBRATION_ATTRIBUTES; break; default: attrs = TOUCH_VIBRATION_ATTRIBUTES; } Loading @@ -225,6 +232,23 @@ public final class HapticFeedbackVibrationProvider { return flags == 0 ? attrs : new VibrationAttributes.Builder(attrs).setFlags(flags).build(); } /** * Returns true if given haptic feedback is restricted to system apps with permission * {@code android.permission.VIBRATE_SYSTEM_CONSTANTS}. * * @param effectId the haptic feedback effect ID to check. * @return true if the haptic feedback is restricted, false otherwise. */ public boolean isRestrictedHapticFeedback(int effectId) { switch (effectId) { case HapticFeedbackConstants.BIOMETRIC_CONFIRM: case HapticFeedbackConstants.BIOMETRIC_REJECT: return true; default: return false; } } /** Dumps relevant state. */ public void dump(String prefix, PrintWriter pw) { pw.print("mHapticTextHandleEnabled="); pw.println(mHapticTextHandleEnabled); Loading services/core/java/com/android/server/vibrator/VibratorManagerService.java +5 −0 Original line number Diff line number Diff line Loading @@ -439,6 +439,11 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { Slog.w(TAG, "performHapticFeedback; haptic vibration provider not ready."); return null; } if (hapticVibrationProvider.isRestrictedHapticFeedback(constant) && !hasPermission(android.Manifest.permission.VIBRATE_SYSTEM_CONSTANTS)) { Slog.w(TAG, "performHapticFeedback; no permission for effect " + constant); return null; } VibrationEffect effect = hapticVibrationProvider.getVibrationForHapticFeedback(constant); if (effect == null) { Slog.w(TAG, "performHapticFeedback; vibration absent for effect " + constant); Loading services/tests/vibrator/AndroidManifest.xml +2 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,8 @@ <uses-permission android:name="android.permission.ACCESS_VIBRATOR_STATE" /> <!-- Required to set always-on vibrations --> <uses-permission android:name="android.permission.VIBRATE_ALWAYS_ON" /> <!-- Required to play system-only haptic feedback constants --> <uses-permission android:name="android.permission.VIBRATE_SYSTEM_CONSTANTS" /> <application android:debuggable="true"> <uses-library android:name="android.test.mock" android:required="true" /> Loading Loading
core/java/android/view/HapticFeedbackConstants.java +17 −5 Original line number Diff line number Diff line Loading @@ -83,11 +83,7 @@ public class HapticFeedbackConstants { */ public static final int TEXT_HANDLE_MOVE = 9; /** * The user unlocked the device * @hide */ public static final int ENTRY_BUMP = 10; // REMOVED: ENTRY_BUMP = 10 /** * The user has moved the dragged object within a droppable area. Loading Loading @@ -229,6 +225,22 @@ public class HapticFeedbackConstants { */ public static final int LONG_PRESS_POWER_BUTTON = 10003; /** * A haptic effect to signal the confirmation of a user biometric authentication * (e.g. fingerprint reading). * This is a private constant to be used only by system apps. * @hide */ public static final int BIOMETRIC_CONFIRM = 10004; /** * A haptic effect to signal the rejection of a user biometric authentication attempt * (e.g. fingerprint reading). * This is a private constant to be used only by system apps. * @hide */ public static final int BIOMETRIC_REJECT = 10005; /** * Flag for {@link View#performHapticFeedback(int, int) * View.performHapticFeedback(int, int)}: Ignore the setting in the Loading
core/res/AndroidManifest.xml +7 −0 Original line number Diff line number Diff line Loading @@ -2593,6 +2593,13 @@ <permission android:name="android.permission.VIBRATE_ALWAYS_ON" android:protectionLevel="signature" /> <!-- Allows access to system-only haptic feedback constants. <p>Protection level: signature @hide --> <permission android:name="android.permission.VIBRATE_SYSTEM_CONSTANTS" android:protectionLevel="signature" /> <!-- @SystemApi Allows access to the vibrator state. <p>Protection level: signature @hide Loading
services/core/java/com/android/server/vibrator/HapticFeedbackVibrationProvider.java +25 −1 Original line number Diff line number Diff line Loading @@ -44,6 +44,8 @@ public final class HapticFeedbackVibrationProvider { VibrationAttributes.createForUsage(VibrationAttributes.USAGE_PHYSICAL_EMULATION); private static final VibrationAttributes HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES = VibrationAttributes.createForUsage(VibrationAttributes.USAGE_HARDWARE_FEEDBACK); private static final VibrationAttributes COMMUNICATION_REQUEST_VIBRATION_ATTRIBUTES = VibrationAttributes.createForUsage(VibrationAttributes.USAGE_COMMUNICATION_REQUEST); private final VibratorInfo mVibratorInfo; private final boolean mHapticTextHandleEnabled; Loading Loading @@ -120,7 +122,6 @@ public final class HapticFeedbackVibrationProvider { return getKeyboardVibration(effectId); case HapticFeedbackConstants.VIRTUAL_KEY_RELEASE: case HapticFeedbackConstants.ENTRY_BUMP: case HapticFeedbackConstants.DRAG_CROSSING: return getVibration( effectId, Loading @@ -131,6 +132,7 @@ public final class HapticFeedbackVibrationProvider { case HapticFeedbackConstants.EDGE_RELEASE: case HapticFeedbackConstants.CALENDAR_DATE: case HapticFeedbackConstants.CONFIRM: case HapticFeedbackConstants.BIOMETRIC_CONFIRM: case HapticFeedbackConstants.GESTURE_START: case HapticFeedbackConstants.SCROLL_ITEM_FOCUS: case HapticFeedbackConstants.SCROLL_LIMIT: Loading @@ -143,6 +145,7 @@ public final class HapticFeedbackVibrationProvider { return getVibration(effectId, VibrationEffect.EFFECT_HEAVY_CLICK); case HapticFeedbackConstants.REJECT: case HapticFeedbackConstants.BIOMETRIC_REJECT: return getVibration(effectId, VibrationEffect.EFFECT_DOUBLE_CLICK); case HapticFeedbackConstants.SAFE_MODE_ENABLED: Loading Loading @@ -207,6 +210,10 @@ public final class HapticFeedbackVibrationProvider { case HapticFeedbackConstants.KEYBOARD_RELEASE: attrs = createKeyboardVibrationAttributes(fromIme); break; case HapticFeedbackConstants.BIOMETRIC_CONFIRM: case HapticFeedbackConstants.BIOMETRIC_REJECT: attrs = COMMUNICATION_REQUEST_VIBRATION_ATTRIBUTES; break; default: attrs = TOUCH_VIBRATION_ATTRIBUTES; } Loading @@ -225,6 +232,23 @@ public final class HapticFeedbackVibrationProvider { return flags == 0 ? attrs : new VibrationAttributes.Builder(attrs).setFlags(flags).build(); } /** * Returns true if given haptic feedback is restricted to system apps with permission * {@code android.permission.VIBRATE_SYSTEM_CONSTANTS}. * * @param effectId the haptic feedback effect ID to check. * @return true if the haptic feedback is restricted, false otherwise. */ public boolean isRestrictedHapticFeedback(int effectId) { switch (effectId) { case HapticFeedbackConstants.BIOMETRIC_CONFIRM: case HapticFeedbackConstants.BIOMETRIC_REJECT: return true; default: return false; } } /** Dumps relevant state. */ public void dump(String prefix, PrintWriter pw) { pw.print("mHapticTextHandleEnabled="); pw.println(mHapticTextHandleEnabled); Loading
services/core/java/com/android/server/vibrator/VibratorManagerService.java +5 −0 Original line number Diff line number Diff line Loading @@ -439,6 +439,11 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { Slog.w(TAG, "performHapticFeedback; haptic vibration provider not ready."); return null; } if (hapticVibrationProvider.isRestrictedHapticFeedback(constant) && !hasPermission(android.Manifest.permission.VIBRATE_SYSTEM_CONSTANTS)) { Slog.w(TAG, "performHapticFeedback; no permission for effect " + constant); return null; } VibrationEffect effect = hapticVibrationProvider.getVibrationForHapticFeedback(constant); if (effect == null) { Slog.w(TAG, "performHapticFeedback; vibration absent for effect " + constant); Loading
services/tests/vibrator/AndroidManifest.xml +2 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,8 @@ <uses-permission android:name="android.permission.ACCESS_VIBRATOR_STATE" /> <!-- Required to set always-on vibrations --> <uses-permission android:name="android.permission.VIBRATE_ALWAYS_ON" /> <!-- Required to play system-only haptic feedback constants --> <uses-permission android:name="android.permission.VIBRATE_SYSTEM_CONSTANTS" /> <application android:debuggable="true"> <uses-library android:name="android.test.mock" android:required="true" /> Loading