• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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