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.IntDef; 20 import android.annotation.RequiresPermission; 21 import android.annotation.SystemService; 22 import android.annotation.UnsupportedAppUsage; 23 import android.app.ActivityThread; 24 import android.content.Context; 25 import android.media.AudioAttributes; 26 import android.util.Log; 27 28 import java.lang.annotation.Retention; 29 import java.lang.annotation.RetentionPolicy; 30 31 /** 32 * Class that operates the vibrator on the device. 33 * <p> 34 * If your process exits, any vibration you started will stop. 35 * </p> 36 */ 37 @SystemService(Context.VIBRATOR_SERVICE) 38 public abstract class Vibrator { 39 private static final String TAG = "Vibrator"; 40 41 /** 42 * Vibration intensity: no vibrations. 43 * @hide 44 */ 45 public static final int VIBRATION_INTENSITY_OFF = 0; 46 47 /** 48 * Vibration intensity: low. 49 * @hide 50 */ 51 public static final int VIBRATION_INTENSITY_LOW = 1; 52 53 /** 54 * Vibration intensity: medium. 55 * @hide 56 */ 57 public static final int VIBRATION_INTENSITY_MEDIUM = 2; 58 59 /** 60 * Vibration intensity: high. 61 * @hide 62 */ 63 public static final int VIBRATION_INTENSITY_HIGH = 3; 64 65 /** @hide */ 66 @Retention(RetentionPolicy.SOURCE) 67 @IntDef(prefix = { "VIBRATION_INTENSITY_" }, value = { 68 VIBRATION_INTENSITY_OFF, 69 VIBRATION_INTENSITY_LOW, 70 VIBRATION_INTENSITY_MEDIUM, 71 VIBRATION_INTENSITY_HIGH 72 }) 73 public @interface VibrationIntensity{} 74 75 private final String mPackageName; 76 // The default vibration intensity level for haptic feedback. 77 @VibrationIntensity 78 private int mDefaultHapticFeedbackIntensity; 79 // The default vibration intensity level for notifications. 80 @VibrationIntensity 81 private int mDefaultNotificationVibrationIntensity; 82 // The default vibration intensity level for ringtones. 83 @VibrationIntensity 84 private int mDefaultRingVibrationIntensity; 85 86 /** 87 * @hide to prevent subclassing from outside of the framework 88 */ 89 @UnsupportedAppUsage Vibrator()90 public Vibrator() { 91 mPackageName = ActivityThread.currentPackageName(); 92 final Context ctx = ActivityThread.currentActivityThread().getSystemContext(); 93 loadVibrationIntensities(ctx); 94 } 95 96 /** 97 * @hide to prevent subclassing from outside of the framework 98 */ Vibrator(Context context)99 protected Vibrator(Context context) { 100 mPackageName = context.getOpPackageName(); 101 loadVibrationIntensities(context); 102 } 103 loadVibrationIntensities(Context context)104 private void loadVibrationIntensities(Context context) { 105 mDefaultHapticFeedbackIntensity = loadDefaultIntensity(context, 106 com.android.internal.R.integer.config_defaultHapticFeedbackIntensity); 107 mDefaultNotificationVibrationIntensity = loadDefaultIntensity(context, 108 com.android.internal.R.integer.config_defaultNotificationVibrationIntensity); 109 mDefaultRingVibrationIntensity = loadDefaultIntensity(context, 110 com.android.internal.R.integer.config_defaultRingVibrationIntensity); 111 } 112 loadDefaultIntensity(Context ctx, int resId)113 private int loadDefaultIntensity(Context ctx, int resId) { 114 return ctx != null ? ctx.getResources().getInteger(resId) : VIBRATION_INTENSITY_MEDIUM; 115 } 116 117 /** 118 * Get the default vibration intensity for haptic feedback. 119 * @hide 120 */ getDefaultHapticFeedbackIntensity()121 public int getDefaultHapticFeedbackIntensity() { 122 return mDefaultHapticFeedbackIntensity; 123 } 124 125 /** 126 * Get the default vibration intensity for notifications. 127 * @hide 128 */ getDefaultNotificationVibrationIntensity()129 public int getDefaultNotificationVibrationIntensity() { 130 return mDefaultNotificationVibrationIntensity; 131 } 132 133 /** Get the default vibration intensity for ringtones. 134 * @hide 135 */ getDefaultRingVibrationIntensity()136 public int getDefaultRingVibrationIntensity() { 137 return mDefaultRingVibrationIntensity; 138 } 139 140 /** 141 * Check whether the hardware has a vibrator. 142 * 143 * @return True if the hardware has a vibrator, else false. 144 */ hasVibrator()145 public abstract boolean hasVibrator(); 146 147 /** 148 * Check whether the vibrator has amplitude control. 149 * 150 * @return True if the hardware can control the amplitude of the vibrations, otherwise false. 151 */ hasAmplitudeControl()152 public abstract boolean hasAmplitudeControl(); 153 154 /** 155 * Vibrate constantly for the specified period of time. 156 * 157 * @param milliseconds The number of milliseconds to vibrate. 158 * 159 * @deprecated Use {@link #vibrate(VibrationEffect)} instead. 160 */ 161 @Deprecated 162 @RequiresPermission(android.Manifest.permission.VIBRATE) vibrate(long milliseconds)163 public void vibrate(long milliseconds) { 164 vibrate(milliseconds, null); 165 } 166 167 /** 168 * Vibrate constantly for the specified period of time. 169 * 170 * @param milliseconds The number of milliseconds to vibrate. 171 * @param attributes {@link AudioAttributes} corresponding to the vibration. For example, 172 * specify {@link AudioAttributes#USAGE_ALARM} for alarm vibrations or 173 * {@link AudioAttributes#USAGE_NOTIFICATION_RINGTONE} for 174 * vibrations associated with incoming calls. 175 * 176 * @deprecated Use {@link #vibrate(VibrationEffect, AudioAttributes)} instead. 177 */ 178 @Deprecated 179 @RequiresPermission(android.Manifest.permission.VIBRATE) vibrate(long milliseconds, AudioAttributes attributes)180 public void vibrate(long milliseconds, AudioAttributes attributes) { 181 try { 182 // This ignores all exceptions to stay compatible with pre-O implementations. 183 VibrationEffect effect = 184 VibrationEffect.createOneShot(milliseconds, VibrationEffect.DEFAULT_AMPLITUDE); 185 vibrate(effect, attributes); 186 } catch (IllegalArgumentException iae) { 187 Log.e(TAG, "Failed to create VibrationEffect", iae); 188 } 189 } 190 191 /** 192 * Vibrate with a given pattern. 193 * 194 * <p> 195 * Pass in an array of ints that are the durations for which to turn on or off 196 * the vibrator in milliseconds. The first value indicates the number of milliseconds 197 * to wait before turning the vibrator on. The next value indicates the number of milliseconds 198 * for which to keep the vibrator on before turning it off. Subsequent values alternate 199 * between durations in milliseconds to turn the vibrator off or to turn the vibrator on. 200 * </p><p> 201 * To cause the pattern to repeat, pass the index into the pattern array at which 202 * to start the repeat, or -1 to disable repeating. 203 * </p> 204 * 205 * @param pattern an array of longs of times for which to turn the vibrator on or off. 206 * @param repeat the index into pattern at which to repeat, or -1 if 207 * you don't want to repeat. 208 * 209 * @deprecated Use {@link #vibrate(VibrationEffect)} instead. 210 */ 211 @Deprecated 212 @RequiresPermission(android.Manifest.permission.VIBRATE) vibrate(long[] pattern, int repeat)213 public void vibrate(long[] pattern, int repeat) { 214 vibrate(pattern, repeat, null); 215 } 216 217 /** 218 * Vibrate with a given pattern. 219 * 220 * <p> 221 * Pass in an array of ints that are the durations for which to turn on or off 222 * the vibrator in milliseconds. The first value indicates the number of milliseconds 223 * to wait before turning the vibrator on. The next value indicates the number of milliseconds 224 * for which to keep the vibrator on before turning it off. Subsequent values alternate 225 * between durations in milliseconds to turn the vibrator off or to turn the vibrator on. 226 * </p><p> 227 * To cause the pattern to repeat, pass the index into the pattern array at which 228 * to start the repeat, or -1 to disable repeating. 229 * </p> 230 * 231 * @param pattern an array of longs of times for which to turn the vibrator on or off. 232 * @param repeat the index into pattern at which to repeat, or -1 if 233 * you don't want to repeat. 234 * @param attributes {@link AudioAttributes} corresponding to the vibration. For example, 235 * specify {@link AudioAttributes#USAGE_ALARM} for alarm vibrations or 236 * {@link AudioAttributes#USAGE_NOTIFICATION_RINGTONE} for 237 * vibrations associated with incoming calls. 238 * 239 * @deprecated Use {@link #vibrate(VibrationEffect, AudioAttributes)} instead. 240 */ 241 @Deprecated 242 @RequiresPermission(android.Manifest.permission.VIBRATE) vibrate(long[] pattern, int repeat, AudioAttributes attributes)243 public void vibrate(long[] pattern, int repeat, AudioAttributes attributes) { 244 // This call needs to continue throwing ArrayIndexOutOfBoundsException but ignore all other 245 // exceptions for compatibility purposes 246 if (repeat < -1 || repeat >= pattern.length) { 247 Log.e(TAG, "vibrate called with repeat index out of bounds" + 248 " (pattern.length=" + pattern.length + ", index=" + repeat + ")"); 249 throw new ArrayIndexOutOfBoundsException(); 250 } 251 252 try { 253 vibrate(VibrationEffect.createWaveform(pattern, repeat), attributes); 254 } catch (IllegalArgumentException iae) { 255 Log.e(TAG, "Failed to create VibrationEffect", iae); 256 } 257 } 258 259 @RequiresPermission(android.Manifest.permission.VIBRATE) vibrate(VibrationEffect vibe)260 public void vibrate(VibrationEffect vibe) { 261 vibrate(vibe, null); 262 } 263 264 @RequiresPermission(android.Manifest.permission.VIBRATE) vibrate(VibrationEffect vibe, AudioAttributes attributes)265 public void vibrate(VibrationEffect vibe, AudioAttributes attributes) { 266 vibrate(Process.myUid(), mPackageName, vibe, null, attributes); 267 } 268 269 /** 270 * Like {@link #vibrate(int, String, VibrationEffect, AudioAttributes)}, but allows the 271 * caller to specify the vibration is owned by someone else and set reason for vibration. 272 * @hide 273 */ 274 @RequiresPermission(android.Manifest.permission.VIBRATE) vibrate(int uid, String opPkg, VibrationEffect vibe, String reason, AudioAttributes attributes)275 public abstract void vibrate(int uid, String opPkg, VibrationEffect vibe, 276 String reason, AudioAttributes attributes); 277 278 /** 279 * Turn the vibrator off. 280 */ 281 @RequiresPermission(android.Manifest.permission.VIBRATE) cancel()282 public abstract void cancel(); 283 } 284