Loading core/java/android/hardware/input/InputManager.java +1 −1 Original line number Diff line number Diff line Loading @@ -1246,7 +1246,7 @@ public final class InputManager { int repeat; if (effect instanceof VibrationEffect.OneShot) { VibrationEffect.OneShot oneShot = (VibrationEffect.OneShot) effect; pattern = new long[] { 0, oneShot.getTiming() }; pattern = new long[] { 0, oneShot.getDuration() }; repeat = -1; } else if (effect instanceof VibrationEffect.Waveform) { VibrationEffect.Waveform waveform = (VibrationEffect.Waveform) effect; Loading core/java/android/os/VibrationEffect.java +173 −44 Original line number Diff line number Diff line Loading @@ -16,7 +16,9 @@ package android.os; import android.hardware.vibrator.V1_0.Constants.EffectStrength; import android.hardware.vibrator.V1_1.Constants.Effect_1_1; import android.util.MathUtils; import java.util.Arrays; Loading @@ -35,6 +37,12 @@ public abstract class VibrationEffect implements Parcelable { */ public static final int DEFAULT_AMPLITUDE = -1; /** * The maximum amplitude value * @hide */ public static final int MAX_AMPLITUDE = 255; /** * A click effect. * Loading Loading @@ -198,38 +206,75 @@ public abstract class VibrationEffect implements Parcelable { /** @hide */ public abstract void validate(); /** * Gets the estimated duration of the vibration in milliseconds. * * For effects without a defined end (e.g. a Waveform with a non-negative repeat index), this * returns Long.MAX_VALUE. For effects with an unknown duration (e.g. Prebaked effects where * the length is device and potentially run-time dependent), this returns -1. * * @hide */ public abstract long getDuration(); /** * Scale the amplitude with the given constraints. * * This assumes that the previous value was in the range [0, MAX_AMPLITUDE] * @hide */ protected static int scale(int amplitude, float gamma, int maxAmplitude) { float val = MathUtils.pow(amplitude / (float) MAX_AMPLITUDE, gamma); return (int) (val * maxAmplitude); } /** @hide */ public static class OneShot extends VibrationEffect implements Parcelable { private long mTiming; private int mAmplitude; private final long mDuration; private final int mAmplitude; public OneShot(Parcel in) { this(in.readLong(), in.readInt()); mDuration = in.readLong(); mAmplitude = in.readInt(); } public OneShot(long milliseconds, int amplitude) { mTiming = milliseconds; mDuration = milliseconds; mAmplitude = amplitude; } public long getTiming() { return mTiming; @Override public long getDuration() { return mDuration; } public int getAmplitude() { return mAmplitude; } /** * Scale the amplitude of this effect. * * @param gamma the gamma adjustment to apply * @param maxAmplitude the new maximum amplitude of the effect * * @return A {@link OneShot} effect with the same timing but scaled amplitude. */ public VibrationEffect scale(float gamma, int maxAmplitude) { int newAmplitude = scale(mAmplitude, gamma, maxAmplitude); return new OneShot(mDuration, newAmplitude); } @Override public void validate() { if (mAmplitude < -1 || mAmplitude == 0 || mAmplitude > 255) { throw new IllegalArgumentException( "amplitude must either be DEFAULT_AMPLITUDE, " + "or between 1 and 255 inclusive (amplitude=" + mAmplitude + ")"); "amplitude must either be DEFAULT_AMPLITUDE, " + "or between 1 and 255 inclusive (amplitude=" + mAmplitude + ")"); } if (mTiming <= 0) { if (mDuration <= 0) { throw new IllegalArgumentException( "timing must be positive (timing=" + mTiming + ")"); "duration must be positive (duration=" + mDuration + ")"); } } Loading @@ -239,26 +284,26 @@ public abstract class VibrationEffect implements Parcelable { return false; } VibrationEffect.OneShot other = (VibrationEffect.OneShot) o; return other.mTiming == mTiming && other.mAmplitude == mAmplitude; return other.mDuration == mDuration && other.mAmplitude == mAmplitude; } @Override public int hashCode() { int result = 17; result = 37 * (int) mTiming; result = 37 * mAmplitude; result += 37 * (int) mDuration; result += 37 * mAmplitude; return result; } @Override public String toString() { return "OneShot{mTiming=" + mTiming +", mAmplitude=" + mAmplitude + "}"; return "OneShot{mDuration=" + mDuration + ", mAmplitude=" + mAmplitude + "}"; } @Override public void writeToParcel(Parcel out, int flags) { out.writeInt(PARCEL_TOKEN_ONE_SHOT); out.writeLong(mTiming); out.writeLong(mDuration); out.writeInt(mAmplitude); } Loading @@ -279,9 +324,9 @@ public abstract class VibrationEffect implements Parcelable { /** @hide */ public static class Waveform extends VibrationEffect implements Parcelable { private long[] mTimings; private int[] mAmplitudes; private int mRepeat; private final long[] mTimings; private final int[] mAmplitudes; private final int mRepeat; public Waveform(Parcel in) { this(in.createLongArray(), in.createIntArray(), in.readInt()); Loading @@ -307,35 +352,69 @@ public abstract class VibrationEffect implements Parcelable { return mRepeat; } @Override public long getDuration() { if (mRepeat >= 0) { return Long.MAX_VALUE; } long duration = 0; for (long d : mTimings) { duration += d; } return duration; } /** * Scale the Waveform with the given gamma and new max amplitude. * * @param gamma the gamma adjustment to apply * @param maxAmplitude the new maximum amplitude of the effect * * @return A {@link Waveform} effect with the same timings and repeat index * but scaled amplitude. */ public VibrationEffect scale(float gamma, int maxAmplitude) { if (gamma == 1.0f && maxAmplitude == MAX_AMPLITUDE) { // Just return a copy of the original if there's no scaling to be done. return new Waveform(mTimings, mAmplitudes, mRepeat); } int[] scaledAmplitudes = Arrays.copyOf(mAmplitudes, mAmplitudes.length); for (int i = 0; i < scaledAmplitudes.length; i++) { scaledAmplitudes[i] = scale(scaledAmplitudes[i], gamma, maxAmplitude); } return new Waveform(mTimings, scaledAmplitudes, mRepeat); } @Override public void validate() { if (mTimings.length != mAmplitudes.length) { throw new IllegalArgumentException( "timing and amplitude arrays must be of equal length" + " (timings.length=" + mTimings.length + ", amplitudes.length=" + mAmplitudes.length + ")"); "timing and amplitude arrays must be of equal length" + " (timings.length=" + mTimings.length + ", amplitudes.length=" + mAmplitudes.length + ")"); } if (!hasNonZeroEntry(mTimings)) { throw new IllegalArgumentException("at least one timing must be non-zero" + " (timings=" + Arrays.toString(mTimings) + ")"); throw new IllegalArgumentException("at least one timing must be non-zero" + " (timings=" + Arrays.toString(mTimings) + ")"); } for (long timing : mTimings) { if (timing < 0) { throw new IllegalArgumentException("timings must all be >= 0" + " (timings=" + Arrays.toString(mTimings) + ")"); throw new IllegalArgumentException("timings must all be >= 0" + " (timings=" + Arrays.toString(mTimings) + ")"); } } for (int amplitude : mAmplitudes) { if (amplitude < -1 || amplitude > 255) { throw new IllegalArgumentException( "amplitudes must all be DEFAULT_AMPLITUDE or between 0 and 255" + " (amplitudes=" + Arrays.toString(mAmplitudes) + ")"); "amplitudes must all be DEFAULT_AMPLITUDE or between 0 and 255" + " (amplitudes=" + Arrays.toString(mAmplitudes) + ")"); } } if (mRepeat < -1 || mRepeat >= mTimings.length) { throw new IllegalArgumentException( "repeat index must be within the bounds of the timings array" + " (timings.length=" + mTimings.length + ", index=" + mRepeat +")"); "repeat index must be within the bounds of the timings array" + " (timings.length=" + mTimings.length + ", index=" + mRepeat + ")"); } } Loading @@ -345,26 +424,26 @@ public abstract class VibrationEffect implements Parcelable { return false; } VibrationEffect.Waveform other = (VibrationEffect.Waveform) o; return Arrays.equals(mTimings, other.mTimings) && Arrays.equals(mAmplitudes, other.mAmplitudes) && mRepeat == other.mRepeat; return Arrays.equals(mTimings, other.mTimings) && Arrays.equals(mAmplitudes, other.mAmplitudes) && mRepeat == other.mRepeat; } @Override public int hashCode() { int result = 17; result = 37 * Arrays.hashCode(mTimings); result = 37 * Arrays.hashCode(mAmplitudes); result = 37 * mRepeat; result += 37 * Arrays.hashCode(mTimings); result += 37 * Arrays.hashCode(mAmplitudes); result += 37 * mRepeat; return result; } @Override public String toString() { return "Waveform{mTimings=" + Arrays.toString(mTimings) + ", mAmplitudes=" + Arrays.toString(mAmplitudes) + ", mRepeat=" + mRepeat + "}"; return "Waveform{mTimings=" + Arrays.toString(mTimings) + ", mAmplitudes=" + Arrays.toString(mAmplitudes) + ", mRepeat=" + mRepeat + "}"; } @Override Loading Loading @@ -402,16 +481,20 @@ public abstract class VibrationEffect implements Parcelable { /** @hide */ public static class Prebaked extends VibrationEffect implements Parcelable { private int mEffectId; private boolean mFallback; private final int mEffectId; private final boolean mFallback; private int mEffectStrength; public Prebaked(Parcel in) { this(in.readInt(), in.readByte() != 0); mEffectStrength = in.readInt(); } public Prebaked(int effectId, boolean fallback) { mEffectId = effectId; mFallback = fallback; mEffectStrength = EffectStrength.MEDIUM; } public int getId() { Loading @@ -426,6 +509,39 @@ public abstract class VibrationEffect implements Parcelable { return mFallback; } @Override public long getDuration() { return -1; } /** * Set the effect strength of the prebaked effect. */ public void setEffectStrength(int strength) { if (!isValidEffectStrength(strength)) { throw new IllegalArgumentException("Invalid effect strength: " + strength); } mEffectStrength = strength; } /** * Set the effect strength. */ public int getEffectStrength() { return mEffectStrength; } private static boolean isValidEffectStrength(int strength) { switch (strength) { case EffectStrength.LIGHT: case EffectStrength.MEDIUM: case EffectStrength.STRONG: return true; default: return false; } } @Override public void validate() { switch (mEffectId) { Loading @@ -437,6 +553,10 @@ public abstract class VibrationEffect implements Parcelable { throw new IllegalArgumentException( "Unknown prebaked effect type (value=" + mEffectId + ")"); } if (!isValidEffectStrength(mEffectStrength)) { throw new IllegalArgumentException( "Unknown prebaked effect strength (value=" + mEffectStrength + ")"); } } @Override Loading @@ -445,17 +565,25 @@ public abstract class VibrationEffect implements Parcelable { return false; } VibrationEffect.Prebaked other = (VibrationEffect.Prebaked) o; return mEffectId == other.mEffectId && mFallback == other.mFallback; return mEffectId == other.mEffectId && mFallback == other.mFallback && mEffectStrength == other.mEffectStrength; } @Override public int hashCode() { return mEffectId; int result = 17; result += 37 * mEffectId; result += 37 * mEffectStrength; return result; } @Override public String toString() { return "Prebaked{mEffectId=" + mEffectId + ", mFallback=" + mFallback + "}"; return "Prebaked{mEffectId=" + mEffectId + ", mEffectStrength=" + mEffectStrength + ", mFallback=" + mFallback + "}"; } Loading @@ -464,6 +592,7 @@ public abstract class VibrationEffect implements Parcelable { out.writeInt(PARCEL_TOKEN_EFFECT); out.writeInt(mEffectId); out.writeByte((byte) (mFallback ? 1 : 0)); out.writeInt(mEffectStrength); } public static final Parcelable.Creator<Prebaked> CREATOR = Loading core/java/android/os/Vibrator.java +54 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.os; import android.annotation.IntDef; import android.annotation.RequiresPermission; import android.annotation.SystemService; import android.app.ActivityThread; Loading @@ -23,6 +24,9 @@ import android.content.Context; import android.media.AudioAttributes; import android.util.Log; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * Class that operates the vibrator on the device. * <p> Loading @@ -33,6 +37,40 @@ import android.util.Log; public abstract class Vibrator { private static final String TAG = "Vibrator"; /** * Vibration intensity: no vibrations. * @hide */ public static final int VIBRATION_INTENSITY_OFF = 0; /** * Vibration intensity: low. * @hide */ public static final int VIBRATION_INTENSITY_LOW = 1; /** * Vibration intensity: medium. * @hide */ public static final int VIBRATION_INTENSITY_MEDIUM = 2; /** * Vibration intensity: high. * @hide */ public static final int VIBRATION_INTENSITY_HIGH = 3; /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = { "VIBRATION_INTENSITY_" }, value = { VIBRATION_INTENSITY_OFF, VIBRATION_INTENSITY_LOW, VIBRATION_INTENSITY_MEDIUM, VIBRATION_INTENSITY_HIGH }) public @interface VibrationIntensity{} private final String mPackageName; /** Loading @@ -49,6 +87,22 @@ public abstract class Vibrator { mPackageName = context.getOpPackageName(); } /** * Get the default vibration intensity for haptic feedback. * @hide */ public int getDefaultHapticFeedbackIntensity() { return VIBRATION_INTENSITY_MEDIUM; } /** * Get the default vibration intensity for notifications and ringtones. * @hide */ public int getDefaultNotificationVibrationIntensity() { return VIBRATION_INTENSITY_HIGH; } /** * Check whether the hardware has a vibrator. * Loading core/java/android/provider/Settings.java +42 −1 Original line number Diff line number Diff line Loading @@ -3174,6 +3174,43 @@ public final class Settings { private static final Validator VIBRATE_INPUT_DEVICES_VALIDATOR = BOOLEAN_VALIDATOR; /** * The intensity of notification vibrations, if configurable. * * Not all devices are capable of changing their vibration intensity; on these devices * there will likely be no difference between the various vibration intensities except for * intensity 0 (off) and the rest. * * <b>Values:</b><br/> * 0 - Vibration is disabled<br/> * 1 - Weak vibrations<br/> * 2 - Medium vibrations<br/> * 3 - Strong vibrations * @hide */ public static final String NOTIFICATION_VIBRATION_INTENSITY = "notification_vibration_intensity"; /** * The intensity of haptic feedback vibrations, if configurable. * * Not all devices are capable of changing their feedback intensity; on these devices * there will likely be no difference between the various vibration intensities except for * intensity 0 (off) and the rest. * * <b>Values:</b><br/> * 0 - Vibration is disabled<br/> * 1 - Weak vibrations<br/> * 2 - Medium vibrations<br/> * 3 - Strong vibrations * @hide */ public static final String HAPTIC_FEEDBACK_INTENSITY = "haptic_feedback_intensity"; private static final Validator VIBRATION_INTENSITY_VALIDATOR = new SettingsValidators.InclusiveIntegerRangeValidator(0, 3); /** * Ringer volume. This is used internally, changing this value will not * change the volume. See AudioManager. Loading Loading @@ -3995,7 +4032,9 @@ public final class Settings { LOCK_TO_APP_ENABLED, NOTIFICATION_SOUND, ACCELEROMETER_ROTATION, SHOW_BATTERY_PERCENT SHOW_BATTERY_PERCENT, NOTIFICATION_VIBRATION_INTENSITY, HAPTIC_FEEDBACK_INTENSITY, }; /** Loading Loading @@ -4136,6 +4175,8 @@ public final class Settings { VALIDATORS.put(MODE_RINGER_STREAMS_AFFECTED, MODE_RINGER_STREAMS_AFFECTED_VALIDATOR); VALIDATORS.put(MUTE_STREAMS_AFFECTED, MUTE_STREAMS_AFFECTED_VALIDATOR); VALIDATORS.put(VIBRATE_ON, VIBRATE_ON_VALIDATOR); VALIDATORS.put(NOTIFICATION_VIBRATION_INTENSITY, VIBRATION_INTENSITY_VALIDATOR); VALIDATORS.put(HAPTIC_FEEDBACK_INTENSITY, VIBRATION_INTENSITY_VALIDATOR); VALIDATORS.put(RINGTONE, RINGTONE_VALIDATOR); VALIDATORS.put(NOTIFICATION_SOUND, NOTIFICATION_SOUND_VALIDATOR); VALIDATORS.put(ALARM_ALERT, ALARM_ALERT_VALIDATOR); Loading services/core/java/com/android/server/VibratorService.java +261 −100 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
core/java/android/hardware/input/InputManager.java +1 −1 Original line number Diff line number Diff line Loading @@ -1246,7 +1246,7 @@ public final class InputManager { int repeat; if (effect instanceof VibrationEffect.OneShot) { VibrationEffect.OneShot oneShot = (VibrationEffect.OneShot) effect; pattern = new long[] { 0, oneShot.getTiming() }; pattern = new long[] { 0, oneShot.getDuration() }; repeat = -1; } else if (effect instanceof VibrationEffect.Waveform) { VibrationEffect.Waveform waveform = (VibrationEffect.Waveform) effect; Loading
core/java/android/os/VibrationEffect.java +173 −44 Original line number Diff line number Diff line Loading @@ -16,7 +16,9 @@ package android.os; import android.hardware.vibrator.V1_0.Constants.EffectStrength; import android.hardware.vibrator.V1_1.Constants.Effect_1_1; import android.util.MathUtils; import java.util.Arrays; Loading @@ -35,6 +37,12 @@ public abstract class VibrationEffect implements Parcelable { */ public static final int DEFAULT_AMPLITUDE = -1; /** * The maximum amplitude value * @hide */ public static final int MAX_AMPLITUDE = 255; /** * A click effect. * Loading Loading @@ -198,38 +206,75 @@ public abstract class VibrationEffect implements Parcelable { /** @hide */ public abstract void validate(); /** * Gets the estimated duration of the vibration in milliseconds. * * For effects without a defined end (e.g. a Waveform with a non-negative repeat index), this * returns Long.MAX_VALUE. For effects with an unknown duration (e.g. Prebaked effects where * the length is device and potentially run-time dependent), this returns -1. * * @hide */ public abstract long getDuration(); /** * Scale the amplitude with the given constraints. * * This assumes that the previous value was in the range [0, MAX_AMPLITUDE] * @hide */ protected static int scale(int amplitude, float gamma, int maxAmplitude) { float val = MathUtils.pow(amplitude / (float) MAX_AMPLITUDE, gamma); return (int) (val * maxAmplitude); } /** @hide */ public static class OneShot extends VibrationEffect implements Parcelable { private long mTiming; private int mAmplitude; private final long mDuration; private final int mAmplitude; public OneShot(Parcel in) { this(in.readLong(), in.readInt()); mDuration = in.readLong(); mAmplitude = in.readInt(); } public OneShot(long milliseconds, int amplitude) { mTiming = milliseconds; mDuration = milliseconds; mAmplitude = amplitude; } public long getTiming() { return mTiming; @Override public long getDuration() { return mDuration; } public int getAmplitude() { return mAmplitude; } /** * Scale the amplitude of this effect. * * @param gamma the gamma adjustment to apply * @param maxAmplitude the new maximum amplitude of the effect * * @return A {@link OneShot} effect with the same timing but scaled amplitude. */ public VibrationEffect scale(float gamma, int maxAmplitude) { int newAmplitude = scale(mAmplitude, gamma, maxAmplitude); return new OneShot(mDuration, newAmplitude); } @Override public void validate() { if (mAmplitude < -1 || mAmplitude == 0 || mAmplitude > 255) { throw new IllegalArgumentException( "amplitude must either be DEFAULT_AMPLITUDE, " + "or between 1 and 255 inclusive (amplitude=" + mAmplitude + ")"); "amplitude must either be DEFAULT_AMPLITUDE, " + "or between 1 and 255 inclusive (amplitude=" + mAmplitude + ")"); } if (mTiming <= 0) { if (mDuration <= 0) { throw new IllegalArgumentException( "timing must be positive (timing=" + mTiming + ")"); "duration must be positive (duration=" + mDuration + ")"); } } Loading @@ -239,26 +284,26 @@ public abstract class VibrationEffect implements Parcelable { return false; } VibrationEffect.OneShot other = (VibrationEffect.OneShot) o; return other.mTiming == mTiming && other.mAmplitude == mAmplitude; return other.mDuration == mDuration && other.mAmplitude == mAmplitude; } @Override public int hashCode() { int result = 17; result = 37 * (int) mTiming; result = 37 * mAmplitude; result += 37 * (int) mDuration; result += 37 * mAmplitude; return result; } @Override public String toString() { return "OneShot{mTiming=" + mTiming +", mAmplitude=" + mAmplitude + "}"; return "OneShot{mDuration=" + mDuration + ", mAmplitude=" + mAmplitude + "}"; } @Override public void writeToParcel(Parcel out, int flags) { out.writeInt(PARCEL_TOKEN_ONE_SHOT); out.writeLong(mTiming); out.writeLong(mDuration); out.writeInt(mAmplitude); } Loading @@ -279,9 +324,9 @@ public abstract class VibrationEffect implements Parcelable { /** @hide */ public static class Waveform extends VibrationEffect implements Parcelable { private long[] mTimings; private int[] mAmplitudes; private int mRepeat; private final long[] mTimings; private final int[] mAmplitudes; private final int mRepeat; public Waveform(Parcel in) { this(in.createLongArray(), in.createIntArray(), in.readInt()); Loading @@ -307,35 +352,69 @@ public abstract class VibrationEffect implements Parcelable { return mRepeat; } @Override public long getDuration() { if (mRepeat >= 0) { return Long.MAX_VALUE; } long duration = 0; for (long d : mTimings) { duration += d; } return duration; } /** * Scale the Waveform with the given gamma and new max amplitude. * * @param gamma the gamma adjustment to apply * @param maxAmplitude the new maximum amplitude of the effect * * @return A {@link Waveform} effect with the same timings and repeat index * but scaled amplitude. */ public VibrationEffect scale(float gamma, int maxAmplitude) { if (gamma == 1.0f && maxAmplitude == MAX_AMPLITUDE) { // Just return a copy of the original if there's no scaling to be done. return new Waveform(mTimings, mAmplitudes, mRepeat); } int[] scaledAmplitudes = Arrays.copyOf(mAmplitudes, mAmplitudes.length); for (int i = 0; i < scaledAmplitudes.length; i++) { scaledAmplitudes[i] = scale(scaledAmplitudes[i], gamma, maxAmplitude); } return new Waveform(mTimings, scaledAmplitudes, mRepeat); } @Override public void validate() { if (mTimings.length != mAmplitudes.length) { throw new IllegalArgumentException( "timing and amplitude arrays must be of equal length" + " (timings.length=" + mTimings.length + ", amplitudes.length=" + mAmplitudes.length + ")"); "timing and amplitude arrays must be of equal length" + " (timings.length=" + mTimings.length + ", amplitudes.length=" + mAmplitudes.length + ")"); } if (!hasNonZeroEntry(mTimings)) { throw new IllegalArgumentException("at least one timing must be non-zero" + " (timings=" + Arrays.toString(mTimings) + ")"); throw new IllegalArgumentException("at least one timing must be non-zero" + " (timings=" + Arrays.toString(mTimings) + ")"); } for (long timing : mTimings) { if (timing < 0) { throw new IllegalArgumentException("timings must all be >= 0" + " (timings=" + Arrays.toString(mTimings) + ")"); throw new IllegalArgumentException("timings must all be >= 0" + " (timings=" + Arrays.toString(mTimings) + ")"); } } for (int amplitude : mAmplitudes) { if (amplitude < -1 || amplitude > 255) { throw new IllegalArgumentException( "amplitudes must all be DEFAULT_AMPLITUDE or between 0 and 255" + " (amplitudes=" + Arrays.toString(mAmplitudes) + ")"); "amplitudes must all be DEFAULT_AMPLITUDE or between 0 and 255" + " (amplitudes=" + Arrays.toString(mAmplitudes) + ")"); } } if (mRepeat < -1 || mRepeat >= mTimings.length) { throw new IllegalArgumentException( "repeat index must be within the bounds of the timings array" + " (timings.length=" + mTimings.length + ", index=" + mRepeat +")"); "repeat index must be within the bounds of the timings array" + " (timings.length=" + mTimings.length + ", index=" + mRepeat + ")"); } } Loading @@ -345,26 +424,26 @@ public abstract class VibrationEffect implements Parcelable { return false; } VibrationEffect.Waveform other = (VibrationEffect.Waveform) o; return Arrays.equals(mTimings, other.mTimings) && Arrays.equals(mAmplitudes, other.mAmplitudes) && mRepeat == other.mRepeat; return Arrays.equals(mTimings, other.mTimings) && Arrays.equals(mAmplitudes, other.mAmplitudes) && mRepeat == other.mRepeat; } @Override public int hashCode() { int result = 17; result = 37 * Arrays.hashCode(mTimings); result = 37 * Arrays.hashCode(mAmplitudes); result = 37 * mRepeat; result += 37 * Arrays.hashCode(mTimings); result += 37 * Arrays.hashCode(mAmplitudes); result += 37 * mRepeat; return result; } @Override public String toString() { return "Waveform{mTimings=" + Arrays.toString(mTimings) + ", mAmplitudes=" + Arrays.toString(mAmplitudes) + ", mRepeat=" + mRepeat + "}"; return "Waveform{mTimings=" + Arrays.toString(mTimings) + ", mAmplitudes=" + Arrays.toString(mAmplitudes) + ", mRepeat=" + mRepeat + "}"; } @Override Loading Loading @@ -402,16 +481,20 @@ public abstract class VibrationEffect implements Parcelable { /** @hide */ public static class Prebaked extends VibrationEffect implements Parcelable { private int mEffectId; private boolean mFallback; private final int mEffectId; private final boolean mFallback; private int mEffectStrength; public Prebaked(Parcel in) { this(in.readInt(), in.readByte() != 0); mEffectStrength = in.readInt(); } public Prebaked(int effectId, boolean fallback) { mEffectId = effectId; mFallback = fallback; mEffectStrength = EffectStrength.MEDIUM; } public int getId() { Loading @@ -426,6 +509,39 @@ public abstract class VibrationEffect implements Parcelable { return mFallback; } @Override public long getDuration() { return -1; } /** * Set the effect strength of the prebaked effect. */ public void setEffectStrength(int strength) { if (!isValidEffectStrength(strength)) { throw new IllegalArgumentException("Invalid effect strength: " + strength); } mEffectStrength = strength; } /** * Set the effect strength. */ public int getEffectStrength() { return mEffectStrength; } private static boolean isValidEffectStrength(int strength) { switch (strength) { case EffectStrength.LIGHT: case EffectStrength.MEDIUM: case EffectStrength.STRONG: return true; default: return false; } } @Override public void validate() { switch (mEffectId) { Loading @@ -437,6 +553,10 @@ public abstract class VibrationEffect implements Parcelable { throw new IllegalArgumentException( "Unknown prebaked effect type (value=" + mEffectId + ")"); } if (!isValidEffectStrength(mEffectStrength)) { throw new IllegalArgumentException( "Unknown prebaked effect strength (value=" + mEffectStrength + ")"); } } @Override Loading @@ -445,17 +565,25 @@ public abstract class VibrationEffect implements Parcelable { return false; } VibrationEffect.Prebaked other = (VibrationEffect.Prebaked) o; return mEffectId == other.mEffectId && mFallback == other.mFallback; return mEffectId == other.mEffectId && mFallback == other.mFallback && mEffectStrength == other.mEffectStrength; } @Override public int hashCode() { return mEffectId; int result = 17; result += 37 * mEffectId; result += 37 * mEffectStrength; return result; } @Override public String toString() { return "Prebaked{mEffectId=" + mEffectId + ", mFallback=" + mFallback + "}"; return "Prebaked{mEffectId=" + mEffectId + ", mEffectStrength=" + mEffectStrength + ", mFallback=" + mFallback + "}"; } Loading @@ -464,6 +592,7 @@ public abstract class VibrationEffect implements Parcelable { out.writeInt(PARCEL_TOKEN_EFFECT); out.writeInt(mEffectId); out.writeByte((byte) (mFallback ? 1 : 0)); out.writeInt(mEffectStrength); } public static final Parcelable.Creator<Prebaked> CREATOR = Loading
core/java/android/os/Vibrator.java +54 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.os; import android.annotation.IntDef; import android.annotation.RequiresPermission; import android.annotation.SystemService; import android.app.ActivityThread; Loading @@ -23,6 +24,9 @@ import android.content.Context; import android.media.AudioAttributes; import android.util.Log; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * Class that operates the vibrator on the device. * <p> Loading @@ -33,6 +37,40 @@ import android.util.Log; public abstract class Vibrator { private static final String TAG = "Vibrator"; /** * Vibration intensity: no vibrations. * @hide */ public static final int VIBRATION_INTENSITY_OFF = 0; /** * Vibration intensity: low. * @hide */ public static final int VIBRATION_INTENSITY_LOW = 1; /** * Vibration intensity: medium. * @hide */ public static final int VIBRATION_INTENSITY_MEDIUM = 2; /** * Vibration intensity: high. * @hide */ public static final int VIBRATION_INTENSITY_HIGH = 3; /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = { "VIBRATION_INTENSITY_" }, value = { VIBRATION_INTENSITY_OFF, VIBRATION_INTENSITY_LOW, VIBRATION_INTENSITY_MEDIUM, VIBRATION_INTENSITY_HIGH }) public @interface VibrationIntensity{} private final String mPackageName; /** Loading @@ -49,6 +87,22 @@ public abstract class Vibrator { mPackageName = context.getOpPackageName(); } /** * Get the default vibration intensity for haptic feedback. * @hide */ public int getDefaultHapticFeedbackIntensity() { return VIBRATION_INTENSITY_MEDIUM; } /** * Get the default vibration intensity for notifications and ringtones. * @hide */ public int getDefaultNotificationVibrationIntensity() { return VIBRATION_INTENSITY_HIGH; } /** * Check whether the hardware has a vibrator. * Loading
core/java/android/provider/Settings.java +42 −1 Original line number Diff line number Diff line Loading @@ -3174,6 +3174,43 @@ public final class Settings { private static final Validator VIBRATE_INPUT_DEVICES_VALIDATOR = BOOLEAN_VALIDATOR; /** * The intensity of notification vibrations, if configurable. * * Not all devices are capable of changing their vibration intensity; on these devices * there will likely be no difference between the various vibration intensities except for * intensity 0 (off) and the rest. * * <b>Values:</b><br/> * 0 - Vibration is disabled<br/> * 1 - Weak vibrations<br/> * 2 - Medium vibrations<br/> * 3 - Strong vibrations * @hide */ public static final String NOTIFICATION_VIBRATION_INTENSITY = "notification_vibration_intensity"; /** * The intensity of haptic feedback vibrations, if configurable. * * Not all devices are capable of changing their feedback intensity; on these devices * there will likely be no difference between the various vibration intensities except for * intensity 0 (off) and the rest. * * <b>Values:</b><br/> * 0 - Vibration is disabled<br/> * 1 - Weak vibrations<br/> * 2 - Medium vibrations<br/> * 3 - Strong vibrations * @hide */ public static final String HAPTIC_FEEDBACK_INTENSITY = "haptic_feedback_intensity"; private static final Validator VIBRATION_INTENSITY_VALIDATOR = new SettingsValidators.InclusiveIntegerRangeValidator(0, 3); /** * Ringer volume. This is used internally, changing this value will not * change the volume. See AudioManager. Loading Loading @@ -3995,7 +4032,9 @@ public final class Settings { LOCK_TO_APP_ENABLED, NOTIFICATION_SOUND, ACCELEROMETER_ROTATION, SHOW_BATTERY_PERCENT SHOW_BATTERY_PERCENT, NOTIFICATION_VIBRATION_INTENSITY, HAPTIC_FEEDBACK_INTENSITY, }; /** Loading Loading @@ -4136,6 +4175,8 @@ public final class Settings { VALIDATORS.put(MODE_RINGER_STREAMS_AFFECTED, MODE_RINGER_STREAMS_AFFECTED_VALIDATOR); VALIDATORS.put(MUTE_STREAMS_AFFECTED, MUTE_STREAMS_AFFECTED_VALIDATOR); VALIDATORS.put(VIBRATE_ON, VIBRATE_ON_VALIDATOR); VALIDATORS.put(NOTIFICATION_VIBRATION_INTENSITY, VIBRATION_INTENSITY_VALIDATOR); VALIDATORS.put(HAPTIC_FEEDBACK_INTENSITY, VIBRATION_INTENSITY_VALIDATOR); VALIDATORS.put(RINGTONE, RINGTONE_VALIDATOR); VALIDATORS.put(NOTIFICATION_SOUND, NOTIFICATION_SOUND_VALIDATOR); VALIDATORS.put(ALARM_ALERT, ALARM_ALERT_VALIDATOR); Loading
services/core/java/com/android/server/VibratorService.java +261 −100 File changed.Preview size limit exceeded, changes collapsed. Show changes