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