1 /* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.os; 18 19 import android.annotation.CallbackExecutor; 20 import android.annotation.FlaggedApi; 21 import android.annotation.IntDef; 22 import android.annotation.NonNull; 23 import android.annotation.Nullable; 24 import android.annotation.RequiresPermission; 25 import android.annotation.SuppressLint; 26 import android.annotation.SystemApi; 27 import android.annotation.SystemService; 28 import android.annotation.TestApi; 29 import android.app.ActivityThread; 30 import android.compat.annotation.UnsupportedAppUsage; 31 import android.content.Context; 32 import android.content.res.Resources; 33 import android.hardware.vibrator.IVibrator; 34 import android.media.AudioAttributes; 35 import android.os.vibrator.Flags; 36 import android.os.vibrator.VendorVibrationSession; 37 import android.os.vibrator.VibrationConfig; 38 import android.os.vibrator.VibratorEnvelopeEffectInfo; 39 import android.os.vibrator.VibratorFrequencyProfile; 40 import android.os.vibrator.VibratorFrequencyProfileLegacy; 41 import android.util.Log; 42 import android.view.HapticFeedbackConstants; 43 44 import java.lang.annotation.Retention; 45 import java.lang.annotation.RetentionPolicy; 46 import java.util.concurrent.Executor; 47 48 /** 49 * Class that operates the vibrator on the device. 50 * <p> 51 * If your process exits, any vibration you started will stop. 52 * </p> 53 */ 54 @SystemService(Context.VIBRATOR_SERVICE) 55 public abstract class Vibrator { 56 private static final String TAG = "Vibrator"; 57 58 /** 59 * Vibration intensity: no vibrations. 60 * 61 * @hide 62 */ 63 @TestApi 64 public static final int VIBRATION_INTENSITY_OFF = 0; 65 66 /** 67 * Vibration intensity: low. 68 * 69 * @hide 70 */ 71 @TestApi 72 public static final int VIBRATION_INTENSITY_LOW = 1; 73 74 /** 75 * Vibration intensity: medium. 76 * 77 * @hide 78 */ 79 @TestApi 80 public static final int VIBRATION_INTENSITY_MEDIUM = 2; 81 82 /** 83 * Vibration intensity: high. 84 * 85 * @hide 86 */ 87 @TestApi 88 public static final int VIBRATION_INTENSITY_HIGH = 3; 89 90 /** 91 * Vibration effect support: unknown 92 * 93 * <p>The hardware doesn't report its supported effects, so we can't determine whether the 94 * effect is supported or not. 95 */ 96 public static final int VIBRATION_EFFECT_SUPPORT_UNKNOWN = 0; 97 98 /** 99 * Vibration effect support: supported 100 * 101 * <p>This effect is supported by the underlying hardware. 102 */ 103 public static final int VIBRATION_EFFECT_SUPPORT_YES = 1; 104 105 /** 106 * Vibration effect support: unsupported 107 * 108 * <p>This effect is <b>not</b> natively supported by the underlying hardware, although 109 * the system may still play a fallback vibration. 110 */ 111 public static final int VIBRATION_EFFECT_SUPPORT_NO = 2; 112 113 /** @hide */ 114 @Retention(RetentionPolicy.SOURCE) 115 @IntDef(prefix = {"VIBRATION_EFFECT_SUPPORT_"}, value = { 116 VIBRATION_EFFECT_SUPPORT_UNKNOWN, 117 VIBRATION_EFFECT_SUPPORT_YES, 118 VIBRATION_EFFECT_SUPPORT_NO, 119 }) 120 public @interface VibrationEffectSupport {} 121 122 /** @hide */ 123 @Retention(RetentionPolicy.SOURCE) 124 @IntDef(prefix = {"VIBRATION_INTENSITY_"}, value = { 125 VIBRATION_INTENSITY_OFF, 126 VIBRATION_INTENSITY_LOW, 127 VIBRATION_INTENSITY_MEDIUM, 128 VIBRATION_INTENSITY_HIGH 129 }) 130 public @interface VibrationIntensity { 131 } 132 133 private final String mPackageName; 134 @Nullable 135 private final Resources mResources; 136 137 // This is lazily loaded only for the few clients that need this (e. Settings app). 138 @Nullable 139 private volatile VibrationConfig mVibrationConfig; 140 141 private VibratorFrequencyProfile mVibratorFrequencyProfile; 142 private VibratorEnvelopeEffectInfo mVibratorEnvelopeEffectInfo; 143 144 /** 145 * @hide to prevent subclassing from outside of the framework 146 */ 147 @UnsupportedAppUsage Vibrator()148 public Vibrator() { 149 mPackageName = ActivityThread.currentPackageName(); 150 mResources = null; 151 } 152 153 /** 154 * @hide to prevent subclassing from outside of the framework 155 */ Vibrator(Context context)156 protected Vibrator(Context context) { 157 mPackageName = context.getOpPackageName(); 158 mResources = context.getResources(); 159 } 160 161 /** 162 * Get the info describing this vibrator. 163 * 164 * @hide 165 */ getInfo()166 public VibratorInfo getInfo() { 167 return VibratorInfo.EMPTY_VIBRATOR_INFO; 168 } 169 170 /** Get the static vibrator configuration from config.xml. */ getConfig()171 private VibrationConfig getConfig() { 172 if (mVibrationConfig == null) { 173 Resources resources = mResources; 174 if (resources == null) { 175 final Context ctx = ActivityThread.currentActivityThread().getSystemContext(); 176 resources = ctx != null ? ctx.getResources() : null; 177 } 178 // This might be constructed more than once, but it only loads static config data from a 179 // xml file, so it would be ok. 180 mVibrationConfig = new VibrationConfig(resources); 181 } 182 return mVibrationConfig; 183 } 184 185 /** 186 * Get the default vibration intensity for given usage. 187 * 188 * @hide 189 */ 190 @TestApi 191 @VibrationIntensity getDefaultVibrationIntensity(@ibrationAttributes.Usage int usage)192 public int getDefaultVibrationIntensity(@VibrationAttributes.Usage int usage) { 193 return getConfig().getDefaultVibrationIntensity(usage); 194 } 195 196 /** 197 * Return the ID of this vibrator. 198 * 199 * @return A non-negative integer representing the id of the vibrator controlled by this 200 * service, or -1 this service is not attached to any physical vibrator. 201 */ getId()202 public int getId() { 203 return getInfo().getId(); 204 } 205 206 /** 207 * Check whether the hardware has a vibrator. 208 * 209 * @return True if the hardware has a vibrator, else false. 210 */ hasVibrator()211 public abstract boolean hasVibrator(); 212 213 /** 214 * Check whether the vibrator has amplitude control. 215 * 216 * @return True if the hardware can control the amplitude of the vibrations, otherwise false. 217 */ hasAmplitudeControl()218 public abstract boolean hasAmplitudeControl(); 219 220 /** 221 * Check whether the vibrator has independent frequency control. 222 * 223 * @return True if the hardware can control the frequency of the vibrations independently of 224 * the vibration amplitude, false otherwise. 225 * @hide 226 */ 227 @TestApi hasFrequencyControl()228 public boolean hasFrequencyControl() { 229 return getInfo().hasFrequencyControl(); 230 } 231 232 /** 233 * Checks whether or not the vibrator supports all components of a given {@link VibrationEffect} 234 * (i.e. the vibrator can play the given effect as intended). 235 * 236 * <p>If this method returns {@code true}, then the VibrationEffect should play as expected. 237 * If {@code false}, playing the VibrationEffect might still make a vibration, but the vibration 238 * may be significantly degraded from the intention. 239 * 240 * <p>This method aggregates the results of feature check methods such as 241 * {@link #hasAmplitudeControl}, {@link #areAllPrimitivesSupported(int...)}, etc, depending 242 * on the features that are actually used by the VibrationEffect. 243 * 244 * @param effect the {@link VibrationEffect} to check if it is supported 245 * @return {@code true} if the vibrator can play the given {@code effect} as intended, 246 * {@code false} otherwise. 247 * 248 * @hide 249 */ areVibrationFeaturesSupported(@onNull VibrationEffect effect)250 public boolean areVibrationFeaturesSupported(@NonNull VibrationEffect effect) { 251 return getInfo().areVibrationFeaturesSupported(effect); 252 } 253 254 /** 255 * Check whether the vibrator has support for vendor-specific effects. 256 * 257 * <p>Vendor vibration effects can be created via {@link VibrationEffect#createVendorEffect}. 258 * 259 * @return True if the hardware can play vendor-specific vibration effects, false otherwise. 260 * @hide 261 */ 262 @SystemApi 263 @FlaggedApi(Flags.FLAG_VENDOR_VIBRATION_EFFECTS) areVendorEffectsSupported()264 public boolean areVendorEffectsSupported() { 265 return getInfo().hasCapability(IVibrator.CAP_PERFORM_VENDOR_EFFECTS); 266 } 267 268 /** 269 * Check whether the vibrator has support for vendor-specific vibration sessions. 270 * 271 * <p>Vendor vibration sessions can be started via {@link #startVendorSession}. 272 * 273 * @return True if the hardware can play vendor-specific vibration sessions, false otherwise. 274 * @hide 275 */ 276 @SystemApi 277 @FlaggedApi(Flags.FLAG_VENDOR_VIBRATION_EFFECTS) areVendorSessionsSupported()278 public boolean areVendorSessionsSupported() { 279 return false; 280 } 281 282 /** 283 * Check whether the vibrator can be controlled by an external service with the 284 * {@link IExternalVibratorService}. 285 * 286 * @return True if the hardware can be controlled by an external service, otherwise false. 287 * @hide 288 */ hasExternalControl()289 public boolean hasExternalControl() { 290 return getInfo().hasCapability(IVibrator.CAP_EXTERNAL_CONTROL); 291 } 292 293 /** 294 * Gets the resonant frequency of the vibrator, if applicable. 295 * 296 * @return the resonant frequency of the vibrator, or {@link Float#NaN NaN} if it's unknown, not 297 * applicable, or if this vibrator is a composite of multiple physical devices with different 298 * frequencies. 299 */ getResonantFrequency()300 public float getResonantFrequency() { 301 return getInfo().getResonantFrequencyHz(); 302 } 303 304 /** 305 * Gets the <a href="https://en.wikipedia.org/wiki/Q_factor">Q factor</a> of the vibrator. 306 * 307 * @return the Q factor of the vibrator, or {@link Float#NaN NaN} if it's unknown, not 308 * applicable, or if this vibrator is a composite of multiple physical devices with different 309 * Q factors. 310 */ getQFactor()311 public float getQFactor() { 312 return getInfo().getQFactor(); 313 } 314 315 /** 316 * Gets the profile that describes the vibrator output across the supported frequency range. 317 * 318 * <p>The profile describes the relative output acceleration that the device can reach when it 319 * vibrates at different frequencies. 320 * 321 * @return The frequency profile for this vibrator, or null if the vibrator does not have 322 * frequency control. If this vibrator is a composite of multiple physical devices then this 323 * will return a profile supported in all devices, or null if the intersection is empty or not 324 * available. 325 * @hide 326 */ 327 @TestApi 328 @SuppressLint("UnflaggedApi") 329 @Nullable getFrequencyProfileLegacy()330 public VibratorFrequencyProfileLegacy getFrequencyProfileLegacy() { 331 VibratorInfo.FrequencyProfileLegacy frequencyProfile = 332 getInfo().getFrequencyProfileLegacy(); 333 if (frequencyProfile.isEmpty()) { 334 return null; 335 } 336 return new VibratorFrequencyProfileLegacy(frequencyProfile); 337 } 338 339 /** 340 * Gets the profile that describes the vibrator output across the supported frequency range. 341 * 342 * <p>The profile describes the output acceleration that the device can reach when it 343 * vibrates at different frequencies. 344 * 345 * @return The frequency profile for this vibrator, or null if the vibrator does not have 346 * frequency control. If this vibrator is a composite of multiple physical devices then this 347 * will return a profile supported in all devices, or null if the intersection is empty or not 348 * available. 349 */ 350 @FlaggedApi(Flags.FLAG_NORMALIZED_PWLE_EFFECTS) 351 @Nullable getFrequencyProfile()352 public VibratorFrequencyProfile getFrequencyProfile() { 353 VibratorInfo.FrequencyProfile frequencyProfile = getInfo().getFrequencyProfile(); 354 if (frequencyProfile.isEmpty()) { 355 return null; 356 } 357 358 if (mVibratorFrequencyProfile == null) { 359 mVibratorFrequencyProfile = new VibratorFrequencyProfile(frequencyProfile); 360 } 361 362 return mVibratorFrequencyProfile; 363 } 364 365 /** 366 * Return the maximum amplitude the vibrator can play using the audio haptic channels. 367 * 368 * <p>This is a positive value, or {@link Float#NaN NaN} if it's unknown. If this returns a 369 * positive value <code>maxAmplitude</code>, then the signals from the haptic channels of audio 370 * tracks should be in the range <code>[-maxAmplitude, maxAmplitude]</code>. 371 * 372 * @return a positive value representing the maximum absolute value the device can play signals 373 * from audio haptic channels, or {@link Float#NaN NaN} if it's unknown. 374 * @hide 375 */ getHapticChannelMaximumAmplitude()376 public float getHapticChannelMaximumAmplitude() { 377 return getConfig().getHapticChannelMaximumAmplitude(); 378 } 379 380 /** 381 * Checks whether the vibrator supports the creation of envelope effects. 382 * 383 * Envelope effects are defined by a series of frequency-amplitude pairs with specified 384 * transition times, allowing the creation of more complex vibration patterns. 385 * 386 * @return True if the hardware supports creating envelope effects, false otherwise. 387 */ 388 @FlaggedApi(Flags.FLAG_NORMALIZED_PWLE_EFFECTS) areEnvelopeEffectsSupported()389 public boolean areEnvelopeEffectsSupported() { 390 return getInfo().areEnvelopeEffectsSupported(); 391 } 392 393 /** 394 * Retrieves the vibrator's capabilities and limitations for envelope effects. 395 * 396 * <p>These parameters can be used with {@link VibrationEffect.WaveformEnvelopeBuilder} 397 * to create custom envelope effects. 398 * 399 * @return The vibrator's envelope effect information, or null if not supported. If this 400 * vibrator is a composite of multiple physical devices then this will return a profile 401 * supported in all devices, or null if the intersection is empty or not available. 402 * 403 * @see VibrationEffect.WaveformEnvelopeBuilder 404 */ 405 @FlaggedApi(Flags.FLAG_NORMALIZED_PWLE_EFFECTS) 406 @NonNull getEnvelopeEffectInfo()407 public VibratorEnvelopeEffectInfo getEnvelopeEffectInfo() { 408 if (mVibratorEnvelopeEffectInfo == null) { 409 mVibratorEnvelopeEffectInfo = new VibratorEnvelopeEffectInfo( 410 getInfo().getMaxEnvelopeEffectSize(), 411 getInfo().getMinEnvelopeEffectControlPointDurationMillis(), 412 getInfo().getMaxEnvelopeEffectControlPointDurationMillis()); 413 } 414 415 return mVibratorEnvelopeEffectInfo; 416 } 417 418 /** 419 * Configure an always-on haptics effect. 420 * 421 * @param alwaysOnId The board-specific always-on ID to configure. 422 * @param effect Vibration effect to assign to always-on id. Passing null will disable it. 423 * @param attributes {@link VibrationAttributes} corresponding to the vibration. For example, 424 * specify {@link VibrationAttributes#USAGE_ALARM} for alarm vibrations or 425 * {@link VibrationAttributes#USAGE_RINGTONE} for vibrations associated with 426 * incoming calls. May only be null when effect is null. 427 * @hide 428 */ 429 @RequiresPermission(android.Manifest.permission.VIBRATE_ALWAYS_ON) setAlwaysOnEffect(int alwaysOnId, @Nullable VibrationEffect effect, @Nullable VibrationAttributes attributes)430 public boolean setAlwaysOnEffect(int alwaysOnId, @Nullable VibrationEffect effect, 431 @Nullable VibrationAttributes attributes) { 432 return setAlwaysOnEffect(Process.myUid(), mPackageName, alwaysOnId, effect, attributes); 433 } 434 435 /** 436 * @hide 437 */ 438 @RequiresPermission(android.Manifest.permission.VIBRATE_ALWAYS_ON) setAlwaysOnEffect(int uid, String opPkg, int alwaysOnId, @Nullable VibrationEffect effect, @Nullable VibrationAttributes attributes)439 public boolean setAlwaysOnEffect(int uid, String opPkg, int alwaysOnId, 440 @Nullable VibrationEffect effect, @Nullable VibrationAttributes attributes) { 441 Log.w(TAG, "Always-on effects aren't supported"); 442 return false; 443 } 444 445 /** 446 * Vibrate constantly for the specified period of time. 447 * 448 * <p>The app should be in the foreground for the vibration to happen.</p> 449 * 450 * @param milliseconds The number of milliseconds to vibrate. 451 * @deprecated Use {@link #vibrate(VibrationEffect)} instead. 452 */ 453 @Deprecated 454 @RequiresPermission(android.Manifest.permission.VIBRATE) vibrate(long milliseconds)455 public void vibrate(long milliseconds) { 456 vibrate(milliseconds, null); 457 } 458 459 /** 460 * Vibrate constantly for the specified period of time. 461 * 462 * <p>The app should be in the foreground for the vibration to happen. Background apps should 463 * specify a ringtone, notification or alarm usage in order to vibrate.</p> 464 * 465 * @param milliseconds The number of milliseconds to vibrate. 466 * @param attributes {@link AudioAttributes} corresponding to the vibration. For example, 467 * specify {@link AudioAttributes#USAGE_ALARM} for alarm vibrations or 468 * {@link AudioAttributes#USAGE_NOTIFICATION_RINGTONE} for 469 * vibrations associated with incoming calls. 470 * @deprecated Use {@link #vibrate(VibrationEffect, VibrationAttributes)} instead. 471 */ 472 @Deprecated 473 @RequiresPermission(android.Manifest.permission.VIBRATE) vibrate(long milliseconds, AudioAttributes attributes)474 public void vibrate(long milliseconds, AudioAttributes attributes) { 475 try { 476 // This ignores all exceptions to stay compatible with pre-O implementations. 477 VibrationEffect effect = 478 VibrationEffect.createOneShot(milliseconds, VibrationEffect.DEFAULT_AMPLITUDE); 479 vibrate(effect, attributes); 480 } catch (IllegalArgumentException iae) { 481 Log.e(TAG, "Failed to create VibrationEffect", iae); 482 } 483 } 484 485 /** 486 * Vibrate with a given pattern. 487 * 488 * <p> 489 * Pass in an array of ints that are the durations for which to turn on or off 490 * the vibrator in milliseconds. The first value indicates the number of milliseconds 491 * to wait before turning the vibrator on. The next value indicates the number of milliseconds 492 * for which to keep the vibrator on before turning it off. Subsequent values alternate 493 * between durations in milliseconds to turn the vibrator off or to turn the vibrator on. 494 * </p><p> 495 * To cause the pattern to repeat, pass the index into the pattern array at which 496 * to start the repeat, or -1 to disable repeating. 497 * </p> 498 * 499 * <p>The app should be in the foreground for the vibration to happen.</p> 500 * 501 * @param pattern an array of longs of times for which to turn the vibrator on or off. 502 * @param repeat the index into pattern at which to repeat, or -1 if 503 * you don't want to repeat. 504 * @deprecated Use {@link #vibrate(VibrationEffect)} instead. 505 */ 506 @Deprecated 507 @RequiresPermission(android.Manifest.permission.VIBRATE) vibrate(long[] pattern, int repeat)508 public void vibrate(long[] pattern, int repeat) { 509 vibrate(pattern, repeat, null); 510 } 511 512 /** 513 * Vibrate with a given pattern. 514 * 515 * <p> 516 * Pass in an array of ints that are the durations for which to turn on or off 517 * the vibrator in milliseconds. The first value indicates the number of milliseconds 518 * to wait before turning the vibrator on. The next value indicates the number of milliseconds 519 * for which to keep the vibrator on before turning it off. Subsequent values alternate 520 * between durations in milliseconds to turn the vibrator off or to turn the vibrator on. 521 * </p><p> 522 * To cause the pattern to repeat, pass the index into the pattern array at which 523 * to start the repeat, or -1 to disable repeating. 524 * </p> 525 * 526 * <p>The app should be in the foreground for the vibration to happen. Background apps should 527 * specify a ringtone, notification or alarm usage in order to vibrate.</p> 528 * 529 * @param pattern an array of longs of times for which to turn the vibrator on or off. 530 * @param repeat the index into pattern at which to repeat, or -1 if 531 * you don't want to repeat. 532 * @param attributes {@link AudioAttributes} corresponding to the vibration. For example, 533 * specify {@link AudioAttributes#USAGE_ALARM} for alarm vibrations or 534 * {@link AudioAttributes#USAGE_NOTIFICATION_RINGTONE} for 535 * vibrations associated with incoming calls. 536 * @deprecated Use {@link #vibrate(VibrationEffect, VibrationAttributes)} instead. 537 */ 538 @Deprecated 539 @RequiresPermission(android.Manifest.permission.VIBRATE) vibrate(long[] pattern, int repeat, AudioAttributes attributes)540 public void vibrate(long[] pattern, int repeat, AudioAttributes attributes) { 541 // This call needs to continue throwing ArrayIndexOutOfBoundsException but ignore all other 542 // exceptions for compatibility purposes 543 if (repeat < -1 || repeat >= pattern.length) { 544 Log.e(TAG, "vibrate called with repeat index out of bounds" + 545 " (pattern.length=" + pattern.length + ", index=" + repeat + ")"); 546 throw new ArrayIndexOutOfBoundsException(); 547 } 548 549 try { 550 vibrate(VibrationEffect.createWaveform(pattern, repeat), attributes); 551 } catch (IllegalArgumentException iae) { 552 Log.e(TAG, "Failed to create VibrationEffect", iae); 553 } 554 } 555 556 /** 557 * Vibrate with a given effect. 558 * 559 * <p>The app should be in the foreground for the vibration to happen.</p> 560 * 561 * @param vibe {@link VibrationEffect} describing the vibration to be performed. 562 */ 563 @RequiresPermission(android.Manifest.permission.VIBRATE) vibrate(VibrationEffect vibe)564 public void vibrate(VibrationEffect vibe) { 565 vibrate(vibe, new VibrationAttributes.Builder().build()); 566 } 567 568 /** 569 * Vibrate with a given effect. 570 * 571 * <p>The app should be in the foreground for the vibration to happen. Background apps should 572 * specify a ringtone, notification or alarm usage in order to vibrate.</p> 573 * 574 * @param vibe {@link VibrationEffect} describing the vibration to be performed. 575 * @param attributes {@link AudioAttributes} corresponding to the vibration. For example, 576 * specify {@link AudioAttributes#USAGE_ALARM} for alarm vibrations or 577 * {@link AudioAttributes#USAGE_NOTIFICATION_RINGTONE} for 578 * vibrations associated with incoming calls. 579 * @deprecated Use {@link #vibrate(VibrationEffect, VibrationAttributes)} instead. 580 */ 581 @RequiresPermission(android.Manifest.permission.VIBRATE) vibrate(VibrationEffect vibe, AudioAttributes attributes)582 public void vibrate(VibrationEffect vibe, AudioAttributes attributes) { 583 vibrate(vibe, 584 attributes == null 585 ? new VibrationAttributes.Builder().build() 586 : new VibrationAttributes.Builder(attributes).build()); 587 } 588 589 /** 590 * Vibrate with a given effect. 591 * 592 * <p>The app should be in the foreground for the vibration to happen. Background apps should 593 * specify a ringtone, notification or alarm usage in order to vibrate.</p> 594 * 595 * @param vibe {@link VibrationEffect} describing the vibration to be performed. 596 * @param attributes {@link VibrationAttributes} corresponding to the vibration. For example, 597 * specify {@link VibrationAttributes#USAGE_ALARM} for alarm vibrations or 598 * {@link VibrationAttributes#USAGE_RINGTONE} for vibrations associated with 599 * incoming calls. 600 */ 601 @RequiresPermission(android.Manifest.permission.VIBRATE) vibrate(@onNull VibrationEffect vibe, @NonNull VibrationAttributes attributes)602 public void vibrate(@NonNull VibrationEffect vibe, @NonNull VibrationAttributes attributes) { 603 vibrate(vibe, attributes, null); 604 } 605 606 /** 607 * Vibrate with a given effect. 608 * 609 * <p>The app should be in the foreground for the vibration to happen. Background apps should 610 * specify a ringtone, notification or alarm usage in order to vibrate.</p> 611 * 612 * @param vibe {@link VibrationEffect} describing the vibration to be performed. 613 * @param attributes {@link VibrationAttributes} corresponding to the vibration. For example, 614 * specify {@link VibrationAttributes#USAGE_ALARM} for alarm vibrations or 615 * {@link VibrationAttributes#USAGE_RINGTONE} for vibrations associated with 616 * incoming calls. 617 * @param reason the reason for this vibration, used for debugging purposes. 618 * @hide 619 */ 620 @RequiresPermission(android.Manifest.permission.VIBRATE) vibrate(@onNull VibrationEffect vibe, @NonNull VibrationAttributes attributes, String reason)621 public void vibrate(@NonNull VibrationEffect vibe, 622 @NonNull VibrationAttributes attributes, String reason) { 623 vibrate(Process.myUid(), mPackageName, vibe, reason, attributes); 624 } 625 626 /** 627 * Like {@link #vibrate(VibrationEffect, VibrationAttributes)}, but allows the 628 * caller to specify the vibration is owned by someone else and set a reason for vibration. 629 * 630 * @hide 631 */ 632 @RequiresPermission(android.Manifest.permission.VIBRATE) vibrate(int uid, String opPkg, @NonNull VibrationEffect vibe, String reason, @NonNull VibrationAttributes attributes)633 public abstract void vibrate(int uid, String opPkg, @NonNull VibrationEffect vibe, 634 String reason, @NonNull VibrationAttributes attributes); 635 636 /** 637 * Performs a haptic feedback. 638 * 639 * <p>A haptic feedback is a short vibration feedback. The type of feedback is identified via 640 * the {@code constant}, which should be one of the effect constants provided in 641 * {@link HapticFeedbackConstants}. The haptic feedback provided for a given effect ID is 642 * consistent across all usages on the same device. 643 * 644 * @param constant the ID for the haptic feedback. This should be one of the constants defined 645 * in {@link HapticFeedbackConstants}. 646 * @param reason the reason for this haptic feedback. 647 * @param flags Additional flags as per {@link HapticFeedbackConstants}. 648 * @param privFlags Additional private flags as per {@link HapticFeedbackConstants}. 649 * 650 * @hide 651 */ performHapticFeedback(int constant, String reason, @HapticFeedbackConstants.Flags int flags, @HapticFeedbackConstants.PrivateFlags int privFlags)652 public void performHapticFeedback(int constant, String reason, 653 @HapticFeedbackConstants.Flags int flags, 654 @HapticFeedbackConstants.PrivateFlags int privFlags) { 655 Log.w(TAG, "performHapticFeedback is not supported"); 656 } 657 658 /** 659 * Performs a haptic feedback. Similar to {@link #performHapticFeedback} but also take into the 660 * consideration the {@link InputDevice} that triggered the haptic 661 * 662 * <p>A haptic feedback is a short vibration feedback. The type of feedback is identified via 663 * the {@code constant}, which should be one of the effect constants provided in 664 * {@link HapticFeedbackConstants}. The haptic feedback provided for a given effect ID is 665 * consistent across all usages on the same device. 666 * 667 * @param constant the ID for the haptic feedback. This should be one of the constants 668 * defined in {@link HapticFeedbackConstants}. 669 * @param inputDeviceId the integer id of the input device that triggered the haptic feedback. 670 * @param inputSource the {@link InputDevice.Source} that triggered the haptic feedback. 671 * @param reason the reason for this haptic feedback. 672 * @param flags Additional flags as per {@link HapticFeedbackConstants}. 673 * @param privFlags Additional private flags as per {@link HapticFeedbackConstants}. 674 * @hide 675 */ performHapticFeedbackForInputDevice( int constant, int inputDeviceId, int inputSource, String reason, @HapticFeedbackConstants.Flags int flags, @HapticFeedbackConstants.PrivateFlags int privFlags)676 public void performHapticFeedbackForInputDevice( 677 int constant, int inputDeviceId, int inputSource, String reason, 678 @HapticFeedbackConstants.Flags int flags, 679 @HapticFeedbackConstants.PrivateFlags int privFlags) { 680 Log.w(TAG, "performHapticFeedbackForInputDevice is not supported"); 681 } 682 683 /** 684 * Query whether the vibrator natively supports the given effects. 685 * 686 * <p>If an effect is not supported, the system may still automatically fall back to playing 687 * a simpler vibration instead, which is not optimised for the specific device. This includes 688 * the unknown case, which can't be determined in advance, that will dynamically attempt to 689 * fall back if the optimised effect fails to play. 690 * 691 * <p>The returned array will be the same length as the query array and the value at a given 692 * index will contain {@link #VIBRATION_EFFECT_SUPPORT_YES} if the effect at that same index 693 * in the querying array is supported, {@link #VIBRATION_EFFECT_SUPPORT_NO} if it isn't 694 * supported, or {@link #VIBRATION_EFFECT_SUPPORT_UNKNOWN} if the system can't determine whether 695 * it's supported or not, as some hardware doesn't report its effect capabilities. 696 * 697 * <p>Use {@link #areAllEffectsSupported(int...)} to get a single combined result, 698 * or for convenience when querying exactly one effect. 699 * 700 * @param effectIds Which effects to query for. 701 * @return An array containing the systems current knowledge about whether the given effects 702 * are natively supported by the device, or not. 703 */ 704 @NonNull 705 @VibrationEffectSupport areEffectsSupported( @onNull @ibrationEffect.EffectType int... effectIds)706 public int[] areEffectsSupported( 707 @NonNull @VibrationEffect.EffectType int... effectIds) { 708 VibratorInfo info = getInfo(); 709 int[] supported = new int[effectIds.length]; 710 for (int i = 0; i < effectIds.length; i++) { 711 supported[i] = info.isEffectSupported(effectIds[i]); 712 } 713 return supported; 714 } 715 716 /** 717 * Query whether the vibrator supports all the given effects. If no argument is provided this 718 * method will always return {@link #VIBRATION_EFFECT_SUPPORT_YES}. 719 * 720 * <p>If an effect is not supported, the system may still automatically fall back to a simpler 721 * vibration instead, which is not optimised for the specific device, however vibration isn't 722 * guaranteed in this case. 723 * 724 * <p>If the result is {@link #VIBRATION_EFFECT_SUPPORT_YES}, all effects in the query are 725 * supported by the hardware. 726 * 727 * <p>If the result is {@link #VIBRATION_EFFECT_SUPPORT_NO}, at least one of the effects in the 728 * query is not supported, and using them may fall back to an un-optimized vibration or no 729 * vibration. 730 * 731 * <p>If the result is {@link #VIBRATION_EFFECT_SUPPORT_UNKNOWN}, the system doesn't know 732 * whether all the effects are supported. It may support any or all of the queried effects, 733 * but there's no way to programmatically know whether a {@link #vibrate} call will successfully 734 * cause a vibration. It's guaranteed, however, that none of the queried effects are 735 * definitively unsupported by the hardware. 736 * 737 * <p>Use {@link #areEffectsSupported(int...)} to get individual results for each effect. 738 * 739 * @param effectIds Which effects to query for. 740 * @return Whether all specified effects are natively supported by the device. Empty query 741 * defaults to {@link #VIBRATION_EFFECT_SUPPORT_YES}. 742 */ 743 @VibrationEffectSupport areAllEffectsSupported( @onNull @ibrationEffect.EffectType int... effectIds)744 public final int areAllEffectsSupported( 745 @NonNull @VibrationEffect.EffectType int... effectIds) { 746 VibratorInfo info = getInfo(); 747 int allSupported = VIBRATION_EFFECT_SUPPORT_YES; 748 for (int effectId : effectIds) { 749 switch (info.isEffectSupported(effectId)) { 750 case VIBRATION_EFFECT_SUPPORT_NO: 751 return VIBRATION_EFFECT_SUPPORT_NO; 752 case VIBRATION_EFFECT_SUPPORT_YES: 753 continue; 754 default: // VIBRATION_EFFECT_SUPPORT_UNKNOWN 755 allSupported = VIBRATION_EFFECT_SUPPORT_UNKNOWN; 756 break; 757 } 758 } 759 return allSupported; 760 } 761 762 /** 763 * Query whether the vibrator supports the given primitives. 764 * 765 * The returned array will be the same length as the query array and the value at a given index 766 * will contain whether the effect at that same index in the querying array is supported or 767 * not. 768 * 769 * <p>If a primitive is not supported by the device, then <em>no vibration</em> will occur if 770 * it is played. 771 * 772 * <p>Use {@link #areAllPrimitivesSupported(int...)} to get a single combined result, 773 * or for convenience when querying exactly one primitive. 774 * 775 * @param primitiveIds Which primitives to query for. 776 * @return Whether the primitives are supported. 777 */ 778 @NonNull arePrimitivesSupported( @onNull @ibrationEffect.Composition.PrimitiveType int... primitiveIds)779 public boolean[] arePrimitivesSupported( 780 @NonNull @VibrationEffect.Composition.PrimitiveType int... primitiveIds) { 781 VibratorInfo info = getInfo(); 782 boolean[] supported = new boolean[primitiveIds.length]; 783 for (int i = 0; i < primitiveIds.length; i++) { 784 supported[i] = info.isPrimitiveSupported(primitiveIds[i]); 785 } 786 return supported; 787 } 788 789 /** 790 * Query whether the vibrator supports all of the given primitives. If no argument is provided 791 * this method will always return {@code true}. 792 * 793 * <p>If a primitive is not supported by the device, then <em>no vibration</em> will occur if 794 * it is played. 795 * 796 * <p>Use {@link #arePrimitivesSupported(int...)} to get individual results for each primitive. 797 * 798 * @param primitiveIds Which primitives to query for. 799 * @return Whether all specified primitives are supported. Empty query defaults to {@code true}. 800 */ areAllPrimitivesSupported( @onNull @ibrationEffect.Composition.PrimitiveType int... primitiveIds)801 public final boolean areAllPrimitivesSupported( 802 @NonNull @VibrationEffect.Composition.PrimitiveType int... primitiveIds) { 803 VibratorInfo info = getInfo(); 804 for (int primitiveId : primitiveIds) { 805 if (!info.isPrimitiveSupported(primitiveId)) { 806 return false; 807 } 808 } 809 return true; 810 } 811 812 /** 813 * Query the estimated durations of the given primitives. 814 * 815 * <p>The returned array will be the same length as the query array and the value at a given 816 * index will contain the duration in milliseconds of the effect at the same index in the 817 * querying array. 818 * 819 * <p>The duration will be positive for primitives that are supported and zero for the 820 * unsupported ones, in correspondence with {@link #arePrimitivesSupported(int...)}. 821 * 822 * @param primitiveIds Which primitives to query for. 823 * @return The duration of each primitive, with zeroes for primitives that are not supported. 824 */ 825 @NonNull getPrimitiveDurations( @onNull @ibrationEffect.Composition.PrimitiveType int... primitiveIds)826 public int[] getPrimitiveDurations( 827 @NonNull @VibrationEffect.Composition.PrimitiveType int... primitiveIds) { 828 VibratorInfo info = getInfo(); 829 int[] durations = new int[primitiveIds.length]; 830 for (int i = 0; i < primitiveIds.length; i++) { 831 durations[i] = info.getPrimitiveDuration(primitiveIds[i]); 832 } 833 return durations; 834 } 835 836 /** 837 * Turn the vibrator off. 838 */ 839 @RequiresPermission(android.Manifest.permission.VIBRATE) cancel()840 public abstract void cancel(); 841 842 /** 843 * Cancel specific types of ongoing vibrations. 844 * 845 * @param usageFilter The type of vibration to be cancelled, represented as a bitwise 846 * combination of {@link VibrationAttributes.Usage} values. 847 * @hide 848 */ 849 @RequiresPermission(android.Manifest.permission.VIBRATE) cancel(int usageFilter)850 public abstract void cancel(int usageFilter); 851 852 /** 853 * Check whether the vibrator is vibrating. 854 * 855 * @return True if the hardware is vibrating, otherwise false. 856 * @hide 857 */ 858 @SystemApi 859 @RequiresPermission(android.Manifest.permission.ACCESS_VIBRATOR_STATE) isVibrating()860 public boolean isVibrating() { 861 return false; 862 } 863 864 /** 865 * Listener for when the vibrator state has changed. 866 * 867 * @see #addVibratorStateListener 868 * @see #removeVibratorStateListener 869 * @hide 870 */ 871 @SystemApi 872 public interface OnVibratorStateChangedListener { 873 /** 874 * Called when the vibrator state has changed. 875 * 876 * @param isVibrating If true, the vibrator has started vibrating. If false, 877 * it's stopped vibrating. 878 */ onVibratorStateChanged(boolean isVibrating)879 void onVibratorStateChanged(boolean isVibrating); 880 } 881 882 /** 883 * Adds a listener for vibrator state changes. Callbacks will be executed on the main thread. 884 * If the listener was previously added and not removed, this call will be ignored. 885 * 886 * @param listener listener to be added 887 * @hide 888 */ 889 @SystemApi 890 @RequiresPermission(android.Manifest.permission.ACCESS_VIBRATOR_STATE) addVibratorStateListener(@onNull OnVibratorStateChangedListener listener)891 public void addVibratorStateListener(@NonNull OnVibratorStateChangedListener listener) { 892 } 893 894 /** 895 * Adds a listener for vibrator state change. If the listener was previously added and not 896 * removed, this call will be ignored. 897 * 898 * @param listener listener to be added 899 * @param executor executor of listener 900 * @hide 901 */ 902 @SystemApi 903 @RequiresPermission(android.Manifest.permission.ACCESS_VIBRATOR_STATE) addVibratorStateListener( @onNull @allbackExecutor Executor executor, @NonNull OnVibratorStateChangedListener listener)904 public void addVibratorStateListener( 905 @NonNull @CallbackExecutor Executor executor, 906 @NonNull OnVibratorStateChangedListener listener) { 907 } 908 909 /** 910 * Removes the listener for vibrator state changes. If the listener was not previously 911 * registered, this call will do nothing. 912 * 913 * @param listener listener to be removed 914 * @hide 915 */ 916 @SystemApi 917 @RequiresPermission(android.Manifest.permission.ACCESS_VIBRATOR_STATE) removeVibratorStateListener(@onNull OnVibratorStateChangedListener listener)918 public void removeVibratorStateListener(@NonNull OnVibratorStateChangedListener listener) { 919 } 920 921 /** 922 * Starts a vibration session in this vibrator. 923 * 924 * <p>The session will start asynchronously once the vibrator control can be acquired. Once it's 925 * started the {@link VendorVibrationSession} will be provided to the callback. This session 926 * should be used to play vibrations until the session is ended or canceled. 927 * 928 * <p>The vendor app will have exclusive control over the vibrator during this session. This 929 * control can be revoked by the vibrator service, which will be notified to the same session 930 * callback with the {@link VendorVibrationSession#STATUS_CANCELED}. 931 * 932 * <p>The {@link VibrationAttributes} will be used to decide the priority of the vendor 933 * vibrations that will be performed in this session. All vibrations within this session will 934 * apply the same attributes. 935 * 936 * @param attrs The {@link VibrationAttributes} corresponding to the vibrations that will be 937 * performed in the session. This will be used to decide the priority of this 938 * session against other system vibrations. 939 * @param reason The description for this session, used for debugging purposes. 940 * @param cancellationSignal A signal to cancel the session before it starts. 941 * @param executor The executor for the session callbacks. 942 * @param callback The {@link VendorVibrationSession.Callback} for the started session. 943 * 944 * @see VendorVibrationSession 945 * @hide 946 */ 947 @SystemApi 948 @FlaggedApi(Flags.FLAG_VENDOR_VIBRATION_EFFECTS) 949 @RequiresPermission(allOf = { 950 android.Manifest.permission.VIBRATE, 951 android.Manifest.permission.VIBRATE_VENDOR_EFFECTS, 952 android.Manifest.permission.START_VIBRATION_SESSIONS, 953 }) startVendorSession(@onNull VibrationAttributes attrs, @Nullable String reason, @Nullable CancellationSignal cancellationSignal, @NonNull Executor executor, @NonNull VendorVibrationSession.Callback callback)954 public void startVendorSession(@NonNull VibrationAttributes attrs, @Nullable String reason, 955 @Nullable CancellationSignal cancellationSignal, @NonNull Executor executor, 956 @NonNull VendorVibrationSession.Callback callback) { 957 Log.w(TAG, "startVendorSession is not supported"); 958 executor.execute(() -> callback.onFinished(VendorVibrationSession.STATUS_UNSUPPORTED)); 959 } 960 } 961