Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0eebf348 authored by Lais Andrade's avatar Lais Andrade
Browse files

Use absolute frequency in WaveformBuilder

Remove the concept of relative frequency and the mapping logic from
VibratorInfo and receive absolute frequency values, in hertz, from
WaveformBuilder.

The clipping logic to make all PWLE amplitudes fit the HAL bandwidth map
still remains.

Bug: 203785430
Test: com.android.server.vibrator.*
Change-Id: Ic01a08d84e66d88acad6db5c704251394afbf1f6
parent 4b10475f
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -1822,9 +1822,9 @@ package android.os {

  public static final class VibrationEffect.WaveformBuilder {
    method @NonNull public android.os.VibrationEffect.WaveformBuilder addRamp(@FloatRange(from=0.0f, to=1.0f) float, @IntRange(from=0) int);
    method @NonNull public android.os.VibrationEffect.WaveformBuilder addRamp(@FloatRange(from=0.0f, to=1.0f) float, @FloatRange(from=-1.0F, to=1.0f) float, @IntRange(from=0) int);
    method @NonNull public android.os.VibrationEffect.WaveformBuilder addRamp(@FloatRange(from=0.0f, to=1.0f) float, @FloatRange(from=1.0f) float, @IntRange(from=0) int);
    method @NonNull public android.os.VibrationEffect.WaveformBuilder addStep(@FloatRange(from=0.0f, to=1.0f) float, @IntRange(from=0) int);
    method @NonNull public android.os.VibrationEffect.WaveformBuilder addStep(@FloatRange(from=0.0f, to=1.0f) float, @FloatRange(from=-1.0F, to=1.0f) float, @IntRange(from=0) int);
    method @NonNull public android.os.VibrationEffect.WaveformBuilder addStep(@FloatRange(from=0.0f, to=1.0f) float, @FloatRange(from=1.0f) float, @IntRange(from=0) int);
    method @NonNull public android.os.VibrationEffect build();
    method @NonNull public android.os.VibrationEffect build(int);
  }
@@ -1982,9 +1982,9 @@ package android.os.vibrator {
    method public int describeContents();
    method public long getDuration();
    method public float getEndAmplitude();
    method public float getEndFrequency();
    method public float getEndFrequencyHz();
    method public float getStartAmplitude();
    method public float getStartFrequency();
    method public float getStartFrequencyHz();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.os.vibrator.RampSegment> CREATOR;
  }
@@ -1993,7 +1993,7 @@ package android.os.vibrator {
    method public int describeContents();
    method public float getAmplitude();
    method public long getDuration();
    method public float getFrequency();
    method public float getFrequencyHz();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.os.vibrator.StepSegment> CREATOR;
  }
+22 −18
Original line number Diff line number Diff line
@@ -260,7 +260,7 @@ public abstract class VibrationEffect implements Parcelable {
        for (int i = 0; i < timings.length; i++) {
            float parsedAmplitude = amplitudes[i] == DEFAULT_AMPLITUDE
                    ? DEFAULT_AMPLITUDE : (float) amplitudes[i] / MAX_AMPLITUDE;
            segments.add(new StepSegment(parsedAmplitude, /* frequency= */ 0, (int) timings[i]));
            segments.add(new StepSegment(parsedAmplitude, /* frequencyHz= */ 0, (int) timings[i]));
        }
        VibrationEffect effect = new Composed(segments, repeat);
        effect.validate();
@@ -866,7 +866,7 @@ public abstract class VibrationEffect implements Parcelable {
            Preconditions.checkArgumentNonnegative(delay);
            if (delay > 0) {
                // Created a segment sustaining the zero amplitude to represent the delay.
                addSegment(new StepSegment(/* amplitude= */ 0, /* frequency= */ 0,
                addSegment(new StepSegment(/* amplitude= */ 0, /* frequencyHz= */ 0,
                        /* duration= */ delay));
            }
            return addSegments(effect);
@@ -1033,26 +1033,27 @@ public abstract class VibrationEffect implements Parcelable {
        @NonNull
        public WaveformBuilder addStep(@FloatRange(from = 0f, to = 1f) float amplitude,
                @IntRange(from = 0) int duration) {
            return addStep(amplitude, getPreviousFrequency(), duration);
            mSegments.add(new StepSegment(amplitude, getPreviousFrequencyHz(), duration));
            return this;
        }

        /**
         * Vibrate with given amplitude for the given duration, in millis, keeping the previous
         * vibration frequency the same.
         * Vibrate with given amplitude and frequency for the given duration, in millis.
         *
         * <p>If the duration is zero the vibrator will jump to new amplitude.
         *
         * @param amplitude The amplitude for this step
         * @param frequency The frequency for this step
         * @param frequencyHz The frequency for this step, in hertz
         * @param duration  The duration of this step in milliseconds
         * @return The {@link WaveformBuilder} object to enable adding multiple steps in chain.
         */
        @SuppressLint("MissingGetterMatchingBuilder")
        @NonNull
        public WaveformBuilder addStep(@FloatRange(from = 0f, to = 1f) float amplitude,
                @FloatRange(from = -1f, to = 1f) float frequency,
                @FloatRange(from = 1f) float frequencyHz,
                @IntRange(from = 0) int duration) {
            mSegments.add(new StepSegment(amplitude, frequency, duration));
            Preconditions.checkArgument(frequencyHz >= 1, "Frequency must be >= 1");
            mSegments.add(new StepSegment(amplitude, frequencyHz, duration));
            return this;
        }

@@ -1070,7 +1071,9 @@ public abstract class VibrationEffect implements Parcelable {
        @NonNull
        public WaveformBuilder addRamp(@FloatRange(from = 0f, to = 1f) float amplitude,
                @IntRange(from = 0) int duration) {
            return addRamp(amplitude, getPreviousFrequency(), duration);
            mSegments.add(new RampSegment(getPreviousAmplitude(), amplitude,
                    getPreviousFrequencyHz(), getPreviousFrequencyHz(), duration));
            return this;
        }

        /**
@@ -1080,22 +1083,23 @@ public abstract class VibrationEffect implements Parcelable {
         * <p>If the duration is zero the vibrator will jump to new amplitude and frequency.
         *
         * @param amplitude The final amplitude this ramp should reach
         * @param frequency The final frequency this ramp should reach
         * @param frequencyHz The final frequency this ramp should reach, in hertz
         * @param duration  The duration of this ramp in milliseconds
         * @return The {@link WaveformBuilder} object to enable adding multiple steps in chain.
         */
        @SuppressLint("MissingGetterMatchingBuilder")
        @NonNull
        public WaveformBuilder addRamp(@FloatRange(from = 0f, to = 1f) float amplitude,
                @FloatRange(from = -1f, to = 1f) float frequency,
                @FloatRange(from = 1f) float frequencyHz,
                @IntRange(from = 0) int duration) {
            mSegments.add(new RampSegment(getPreviousAmplitude(), amplitude, getPreviousFrequency(),
                    frequency, duration));
            Preconditions.checkArgument(frequencyHz >= 1, "Frequency must be >= 1");
            mSegments.add(new RampSegment(getPreviousAmplitude(), amplitude,
                    getPreviousFrequencyHz(), frequencyHz, duration));
            return this;
        }

        /**
         * Compose all of the steps together into a single {@link VibrationEffect}.
         * Compose all the steps together into a single {@link VibrationEffect}.
         *
         * The {@link WaveformBuilder} object is still valid after this call, so you can
         * continue adding more primitives to it and generating more {@link VibrationEffect}s by
@@ -1109,7 +1113,7 @@ public abstract class VibrationEffect implements Parcelable {
        }

        /**
         * Compose all of the steps together into a single {@link VibrationEffect}.
         * Compose all the steps together into a single {@link VibrationEffect}.
         *
         * <p>To cause the pattern to repeat, pass the index at which to start the repetition
         * (starting at 0), or -1 to disable repeating.
@@ -1131,13 +1135,13 @@ public abstract class VibrationEffect implements Parcelable {
            return effect;
        }

        private float getPreviousFrequency() {
        private float getPreviousFrequencyHz() {
            if (!mSegments.isEmpty()) {
                VibrationEffectSegment segment = mSegments.get(mSegments.size() - 1);
                if (segment instanceof StepSegment) {
                    return ((StepSegment) segment).getFrequency();
                    return ((StepSegment) segment).getFrequencyHz();
                } else if (segment instanceof RampSegment) {
                    return ((RampSegment) segment).getEndFrequency();
                    return ((RampSegment) segment).getEndFrequencyHz();
                }
            }
            return 0;
+0 −39
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@
package android.os;

import android.annotation.CallbackExecutor;
import android.annotation.FloatRange;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -30,7 +29,6 @@ import android.content.Context;
import android.hardware.vibrator.IVibrator;
import android.media.AudioAttributes;
import android.util.Log;
import android.util.Range;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -270,43 +268,6 @@ public abstract class Vibrator {
        return getInfo().getQFactor();
    }

    /**
     * Return a range of relative frequency values supported by the vibrator.
     *
     * <p>These values can be used to create waveforms that controls the vibration frequency via
     * {@link VibrationEffect.WaveformBuilder}.
     *
     * @return A range of relative frequency values supported. The range will always contain the
     * value 0, representing the device resonant frequency. Devices without frequency control will
     * return the range [0,0]. Devices with frequency control will always return a range containing
     * the safe range [-1, 1].
     * @hide
     */
    public Range<Float> getRelativeFrequencyRange() {
        return getInfo().getFrequencyRange();
    }

    /**
     * Return the maximum amplitude the vibrator can play at given relative frequency.
     *
     * <p>Devices without frequency control will return 1 for the input zero (resonant frequency),
     * and 0 to any other input.
     *
     * <p>Devices with frequency control will return the supported value, for input in
     * {@link #getRelativeFrequencyRange()}, and 0 for any other input.
     *
     * <p>These values can be used to create waveforms that plays vibrations outside the resonant
     * frequency via {@link VibrationEffect.WaveformBuilder}.
     *
     * @return a value in [0,1] representing the maximum amplitude the device can play at given
     * relative frequency.
     * @hide
     */
    @FloatRange(from = 0, to = 1)
    public float getMaximumAmplitude(float relativeFrequency) {
        return getInfo().getMaxAmplitude(relativeFrequency);
    }

    /**
     * Return the maximum amplitude the vibrator can play using the audio haptic channels.
     *
+59 −128

File changed.

Preview size limit exceeded, changes collapsed.

+31 −18
Original line number Diff line number Diff line
@@ -29,14 +29,20 @@ import java.util.Objects;
 * Representation of {@link VibrationEffectSegment} that ramps vibration amplitude and/or frequency
 * for a specified duration.
 *
 * <p>The amplitudes are expressed by float values in the range [0, 1], representing the relative
 * output acceleration for the vibrator. The frequencies are expressed in hertz by positive finite
 * float values. The special value zero is used here for an unspecified frequency, and will be
 * automatically mapped to the device's default vibration frequency (usually the resonant
 * frequency).
 *
 * @hide
 */
@TestApi
public final class RampSegment extends VibrationEffectSegment {
    private final float mStartAmplitude;
    private final float mStartFrequency;
    private final float mStartFrequencyHz;
    private final float mEndAmplitude;
    private final float mEndFrequency;
    private final float mEndFrequencyHz;
    private final int mDuration;

    RampSegment(@NonNull Parcel in) {
@@ -44,12 +50,12 @@ public final class RampSegment extends VibrationEffectSegment {
    }

    /** @hide */
    public RampSegment(float startAmplitude, float endAmplitude, float startFrequency,
            float endFrequency, int duration) {
    public RampSegment(float startAmplitude, float endAmplitude, float startFrequencyHz,
            float endFrequencyHz, int duration) {
        mStartAmplitude = startAmplitude;
        mEndAmplitude = endAmplitude;
        mStartFrequency = startFrequency;
        mEndFrequency = endFrequency;
        mStartFrequencyHz = startFrequencyHz;
        mEndFrequencyHz = endFrequencyHz;
        mDuration = duration;
    }

@@ -61,8 +67,8 @@ public final class RampSegment extends VibrationEffectSegment {
        RampSegment other = (RampSegment) o;
        return Float.compare(mStartAmplitude, other.mStartAmplitude) == 0
                && Float.compare(mEndAmplitude, other.mEndAmplitude) == 0
                && Float.compare(mStartFrequency, other.mStartFrequency) == 0
                && Float.compare(mEndFrequency, other.mEndFrequency) == 0
                && Float.compare(mStartFrequencyHz, other.mStartFrequencyHz) == 0
                && Float.compare(mEndFrequencyHz, other.mEndFrequencyHz) == 0
                && mDuration == other.mDuration;
    }

@@ -74,12 +80,12 @@ public final class RampSegment extends VibrationEffectSegment {
        return mEndAmplitude;
    }

    public float getStartFrequency() {
        return mStartFrequency;
    public float getStartFrequencyHz() {
        return mStartFrequencyHz;
    }

    public float getEndFrequency() {
        return mEndFrequency;
    public float getEndFrequencyHz() {
        return mEndFrequencyHz;
    }

    @Override
@@ -102,6 +108,12 @@ public final class RampSegment extends VibrationEffectSegment {
    /** @hide */
    @Override
    public void validate() {
        Preconditions.checkArgumentNonNegative(mStartFrequencyHz,
                "Frequencies must all be >= 0, got start frequency of " + mStartFrequencyHz);
        Preconditions.checkArgumentFinite(mStartFrequencyHz, "startFrequencyHz");
        Preconditions.checkArgumentNonNegative(mEndFrequencyHz,
                "Frequencies must all be >= 0, got end frequency of " + mEndFrequencyHz);
        Preconditions.checkArgumentFinite(mEndFrequencyHz, "endFrequencyHz");
        Preconditions.checkArgumentNonnegative(mDuration,
                "Durations must all be >= 0, got " + mDuration);
        Preconditions.checkArgumentInRange(mStartAmplitude, 0f, 1f, "startAmplitude");
@@ -126,7 +138,8 @@ public final class RampSegment extends VibrationEffectSegment {
                && Float.compare(mEndAmplitude, newEndAmplitude) == 0) {
            return this;
        }
        return new RampSegment(newStartAmplitude, newEndAmplitude, mStartFrequency, mEndFrequency,
        return new RampSegment(newStartAmplitude, newEndAmplitude, mStartFrequencyHz,
                mEndFrequencyHz,
                mDuration);
    }

@@ -139,7 +152,7 @@ public final class RampSegment extends VibrationEffectSegment {

    @Override
    public int hashCode() {
        return Objects.hash(mStartAmplitude, mEndAmplitude, mStartFrequency, mEndFrequency,
        return Objects.hash(mStartAmplitude, mEndAmplitude, mStartFrequencyHz, mEndFrequencyHz,
                mDuration);
    }

@@ -147,8 +160,8 @@ public final class RampSegment extends VibrationEffectSegment {
    public String toString() {
        return "Ramp{startAmplitude=" + mStartAmplitude
                + ", endAmplitude=" + mEndAmplitude
                + ", startFrequency=" + mStartFrequency
                + ", endFrequency=" + mEndFrequency
                + ", startFrequencyHz=" + mStartFrequencyHz
                + ", endFrequencyHz=" + mEndFrequencyHz
                + ", duration=" + mDuration
                + "}";
    }
@@ -163,8 +176,8 @@ public final class RampSegment extends VibrationEffectSegment {
        out.writeInt(PARCEL_TOKEN_RAMP);
        out.writeFloat(mStartAmplitude);
        out.writeFloat(mEndAmplitude);
        out.writeFloat(mStartFrequency);
        out.writeFloat(mEndFrequency);
        out.writeFloat(mStartFrequencyHz);
        out.writeFloat(mEndFrequencyHz);
        out.writeInt(mDuration);
    }

Loading