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

Commit a7189d86 authored by Ahmad Khalil's avatar Ahmad Khalil
Browse files

Introduce VibratorEnvelopeEffectInfo class

The new class will encapsulate all envelope effect APIs.

Bug: 373656657
Flag: android.os.vibrator.normalized_pwle_effects
Test: atest FrameworksVibratorCoreTests
Change-Id: I4bc8502a091eaab61711ed54ab804a3e2b58e378
parent e4df69fd
Loading
Loading
Loading
Loading
+11 −4
Original line number Diff line number Diff line
@@ -34614,12 +34614,9 @@ package android.os {
    method @FlaggedApi("android.os.vibrator.normalized_pwle_effects") public boolean areEnvelopeEffectsSupported();
    method @NonNull public boolean[] arePrimitivesSupported(@NonNull int...);
    method @RequiresPermission(android.Manifest.permission.VIBRATE) public abstract void cancel();
    method @FlaggedApi("android.os.vibrator.normalized_pwle_effects") @NonNull public android.os.vibrator.VibratorEnvelopeEffectInfo getEnvelopeEffectInfo();
    method @FlaggedApi("android.os.vibrator.normalized_pwle_effects") @Nullable public android.os.vibrator.VibratorFrequencyProfile getFrequencyProfile();
    method public int getId();
    method @FlaggedApi("android.os.vibrator.normalized_pwle_effects") public int getMaxEnvelopeEffectControlPointDurationMillis();
    method @FlaggedApi("android.os.vibrator.normalized_pwle_effects") public int getMaxEnvelopeEffectDurationMillis();
    method @FlaggedApi("android.os.vibrator.normalized_pwle_effects") public int getMaxEnvelopeEffectSize();
    method @FlaggedApi("android.os.vibrator.normalized_pwle_effects") public int getMinEnvelopeEffectControlPointDurationMillis();
    method @NonNull public int[] getPrimitiveDurations(@NonNull int...);
    method public float getQFactor();
    method public float getResonantFrequency();
@@ -34970,6 +34967,16 @@ package android.os.strictmode {
package android.os.vibrator {
  @FlaggedApi("android.os.vibrator.normalized_pwle_effects") public final class VibratorEnvelopeEffectInfo implements android.os.Parcelable {
    method public int describeContents();
    method public long getMaxControlPointDurationMillis();
    method public long getMaxDurationMillis();
    method public int getMaxSize();
    method public long getMinControlPointDurationMillis();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.os.vibrator.VibratorEnvelopeEffectInfo> CREATOR;
  }
  @FlaggedApi("android.os.vibrator.normalized_pwle_effects") public final class VibratorFrequencyProfile {
    method @FlaggedApi("android.os.vibrator.normalized_pwle_effects") @NonNull public android.util.SparseArray<java.lang.Float> getFrequenciesOutputAcceleration();
    method @FlaggedApi("android.os.vibrator.normalized_pwle_effects") @Nullable public android.util.Range<java.lang.Float> getFrequencyRange(float);
+5 −4
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ import android.os.vibrator.PwleSegment;
import android.os.vibrator.RampSegment;
import android.os.vibrator.StepSegment;
import android.os.vibrator.VibrationEffectSegment;
import android.os.vibrator.VibratorEnvelopeEffectInfo;
import android.os.vibrator.VibratorFrequencyProfileLegacy;
import android.util.MathUtils;

@@ -1819,12 +1820,12 @@ public abstract class VibrationEffect implements Parcelable {
     *
     * <p>You can use the following APIs to obtain these limits:
     * <ul>
     * <li>Maximum envelope control points: {@link Vibrator#getMaxEnvelopeEffectSize()}</li>
     * <li>Maximum envelope control points: {@link VibratorEnvelopeEffectInfo#getMaxSize()}
     * <li>Minimum control point duration:
     * {@link Vibrator#getMinEnvelopeEffectControlPointDurationMillis()}</li>
     * {@link VibratorEnvelopeEffectInfo#getMinControlPointDurationMillis()}
     * <li>Maximum control point duration:
     * {@link Vibrator#getMaxEnvelopeEffectControlPointDurationMillis()}</li>
     * <li>Maximum total effect duration: {@link Vibrator#getMaxEnvelopeEffectDurationMillis()}</li>
     * {@link VibratorEnvelopeEffectInfo#getMaxControlPointDurationMillis()}
     * <li>Maximum total effect duration: {@link VibratorEnvelopeEffectInfo#getMaxDurationMillis()}
     * </ul>
     *
     * @see VibrationEffect#startWaveformEnvelope()
+25 −59
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import android.media.AudioAttributes;
import android.os.vibrator.Flags;
import android.os.vibrator.VendorVibrationSession;
import android.os.vibrator.VibrationConfig;
import android.os.vibrator.VibratorEnvelopeEffectInfo;
import android.os.vibrator.VibratorFrequencyProfile;
import android.os.vibrator.VibratorFrequencyProfileLegacy;
import android.util.Log;
@@ -137,6 +138,9 @@ public abstract class Vibrator {
    @Nullable
    private volatile VibrationConfig mVibrationConfig;

    private VibratorFrequencyProfile mVibratorFrequencyProfile;
    private VibratorEnvelopeEffectInfo mVibratorEnvelopeEffectInfo;

    /**
     * @hide to prevent subclassing from outside of the framework
     */
@@ -351,7 +355,11 @@ public abstract class Vibrator {
            return null;
        }

        return new VibratorFrequencyProfile(frequencyProfile);
        if (mVibratorFrequencyProfile == null) {
            mVibratorFrequencyProfile = new VibratorFrequencyProfile(frequencyProfile);
        }

        return mVibratorFrequencyProfile;
    }

    /**
@@ -383,70 +391,28 @@ public abstract class Vibrator {
    }

    /**
     * Retrieves the maximum duration supported for an envelope effect, in milliseconds.
     *
     * <p>If the device supports envelope effects (check {@link #areEnvelopeEffectsSupported}),
     * this value will be positive. Devices with envelope effects capabilities guarantees a
     * maximum duration equivalent to the product of {@link #getMaxEnvelopeEffectSize()} and
     * {@link #getMaxEnvelopeEffectControlPointDurationMillis()}. If the device does not support
     * envelope effects, this method will return 0.
     *
     * @return The maximum duration (in milliseconds) allowed for an envelope effect, or 0 if
     * envelope effects are not supported.
     */
    @FlaggedApi(Flags.FLAG_NORMALIZED_PWLE_EFFECTS)
    public int getMaxEnvelopeEffectDurationMillis() {
        return getInfo().getMaxEnvelopeEffectDurationMillis();
    }

    /**
     * Retrieves the maximum number of control points supported for an envelope effect.
     *
     * <p>If the device supports envelope effects (check {@link #areEnvelopeEffectsSupported}),
     * this value will be positive. Devices with envelope effects capabilities guarantee support
     * for a minimum of 16 control points. If the device does not support envelope effects,
     * this method will return 0.
     * Retrieves the vibrator's capabilities and limitations for envelope effects.
     *
     * @return the maximum number of control points allowed for an envelope effect, or 0 if
     * envelope effects are not supported.
     */
    @FlaggedApi(Flags.FLAG_NORMALIZED_PWLE_EFFECTS)
    public int getMaxEnvelopeEffectSize() {
        return getInfo().getMaxEnvelopeEffectSize();
    }

    /**
     * Retrieves the minimum duration supported between two control points within an envelope
     * effect, in milliseconds.
     * <p>These parameters can be used with {@link VibrationEffect.WaveformEnvelopeBuilder}
     * to create custom envelope effects.
     *
     * <p>If the device supports envelope effects (check {@link #areEnvelopeEffectsSupported}),
     * this value will be positive. Devices with envelope effects capabilities guarantee
     * support for durations down to at least 20 milliseconds. If the device does
     * not support envelope effects, this method will return 0.
     * @return The vibrator's envelope effect information, or null if not supported. If this
     * vibrator is a composite of multiple physical devices then this will return a profile
     * supported in all devices, or null if the intersection is empty or not available.
     *
     * @return the minimum allowed duration between two control points in an envelope effect,
     * or 0 if envelope effects are not supported.
     * @see VibrationEffect.WaveformEnvelopeBuilder
     */
    @FlaggedApi(Flags.FLAG_NORMALIZED_PWLE_EFFECTS)
    public int getMinEnvelopeEffectControlPointDurationMillis() {
        return getInfo().getMinEnvelopeEffectControlPointDurationMillis();
    @NonNull
    public VibratorEnvelopeEffectInfo getEnvelopeEffectInfo() {
        if (mVibratorEnvelopeEffectInfo == null) {
            mVibratorEnvelopeEffectInfo = new VibratorEnvelopeEffectInfo(
                    getInfo().getMaxEnvelopeEffectSize(),
                    getInfo().getMinEnvelopeEffectControlPointDurationMillis(),
                    getInfo().getMaxEnvelopeEffectControlPointDurationMillis());
        }

    /**
     * Retrieves the maximum duration supported between two control points within an envelope
     * effect, in milliseconds.
     *
     * <p>If the device supports envelope effects (check {@link #areEnvelopeEffectsSupported}),
     * this value will be positive. Devices with envelope effects capabilities guarantee support
     * for durations up to at least 1 second. If the device does not support envelope effects,
     * this method will return 0.
     *
     * @return the maximum allowed duration between two control points in an envelope effect,
     * or 0 if envelope effects are not supported.
     */
    @FlaggedApi(Flags.FLAG_NORMALIZED_PWLE_EFFECTS)
    public int getMaxEnvelopeEffectControlPointDurationMillis() {
        return getInfo().getMaxEnvelopeEffectControlPointDurationMillis();
        return mVibratorEnvelopeEffectInfo;
    }

    /**
+197 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.os.vibrator;

import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.VibrationEffect;

import java.util.Objects;

/**
 * Provides information about the vibrator hardware capabilities and limitations regarding
 * waveform envelope effects. This includes:
 * <ul>
 * <li>Maximum number of control points supported.
 * <li>Minimum and maximum duration for individual segments.
 * <li>Maximum total duration for an envelope effect.
 * </ul>
 *
 * <p>This information can be used to help construct waveform envelope effects with
 * {@link VibrationEffect#startWaveformEnvelope()}. When designing these effects, it is also
 * recommended to check the {@link VibratorFrequencyProfile} for information about the supported
 * frequency range and the vibrator's output response.
 *
 * @see VibrationEffect#startWaveformEnvelope()
 * @see VibratorFrequencyProfile
 */
@FlaggedApi(Flags.FLAG_NORMALIZED_PWLE_EFFECTS)
public final class VibratorEnvelopeEffectInfo implements Parcelable {
    private final int mMaxSize;
    private final long mMinControlPointDurationMillis;
    private final long mMaxControlPointDurationMillis;

    VibratorEnvelopeEffectInfo(Parcel in) {
        mMaxSize = in.readInt();
        mMinControlPointDurationMillis = in.readLong();
        mMaxControlPointDurationMillis = in.readLong();
    }

    /**
     * Default constructor.
     *
     * @param maxSize                       The maximum number of control points supported for an
     *                                      envelope effect.
     * @param minControlPointDurationMillis The minimum duration supported between two control
     *                                      points within an envelope effect.
     * @param maxControlPointDurationMillis The maximum duration supported between two control
     *                                      points within an envelope effect.
     * @hide
     */
    public VibratorEnvelopeEffectInfo(int maxSize,
            long minControlPointDurationMillis,
            long maxControlPointDurationMillis) {
        mMaxSize = maxSize;
        mMinControlPointDurationMillis = minControlPointDurationMillis;
        mMaxControlPointDurationMillis = maxControlPointDurationMillis;
    }

    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        dest.writeInt(mMaxSize);
        dest.writeLong(mMinControlPointDurationMillis);
        dest.writeLong(mMaxControlPointDurationMillis);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof VibratorEnvelopeEffectInfo)) {
            return false;
        }
        VibratorEnvelopeEffectInfo other = (VibratorEnvelopeEffectInfo) o;
        return mMaxSize == other.mMaxSize
                && mMinControlPointDurationMillis == other.mMinControlPointDurationMillis
                && mMaxControlPointDurationMillis == other.mMaxControlPointDurationMillis;
    }

    @Override
    public int hashCode() {
        return Objects.hash(mMaxSize,
                mMinControlPointDurationMillis,
                mMaxControlPointDurationMillis);
    }

    @Override
    public String toString() {
        return "VibratorEnvelopeEffectInfo{"
                + ", mMaxSize=" + mMaxSize
                + ", mMinControlPointDurationMillis=" + mMinControlPointDurationMillis
                + ", mMaxControlPointDurationMillis=" + mMaxControlPointDurationMillis
                + '}';
    }

    @NonNull
    public static final Creator<VibratorEnvelopeEffectInfo> CREATOR =
            new Creator<VibratorEnvelopeEffectInfo>() {
                @Override
                public VibratorEnvelopeEffectInfo createFromParcel(Parcel in) {
                    return new VibratorEnvelopeEffectInfo(in);
                }

                @Override
                public VibratorEnvelopeEffectInfo[] newArray(int size) {
                    return new VibratorEnvelopeEffectInfo[size];
                }
            };

    /**
     * Retrieves the maximum duration supported for an envelope effect, in milliseconds.
     *
     * <p>If the device supports envelope effects
     * (check {@link android.os.VibratorInfo#areEnvelopeEffectsSupported}), this value will be
     * positive. Devices with envelope effects capabilities guarantees a maximum duration
     * equivalent to the product of {@link #getMaxSize()} and
     * {@link #getMaxControlPointDurationMillis()}. If the device does not support
     * envelope effects, this method will return 0.
     *
     * @return The maximum duration (in milliseconds) allowed for an envelope effect, or 0 if
     * envelope effects are not supported.
     */
    public long getMaxDurationMillis() {
        return mMaxSize * mMaxControlPointDurationMillis;
    }

    /**
     * Retrieves the maximum number of control points supported for an envelope effect.
     *
     * <p>If the device supports envelope effects
     * (check {@link android.os.VibratorInfo#areEnvelopeEffectsSupported}), this value will be
     * positive. Devices with envelope effects capabilities guarantee support for a minimum of
     * 16 control points. If the device does not support envelope effects, this method will
     * return 0.
     *
     * @return the maximum number of control points allowed for an envelope effect, or 0 if
     * envelope effects are not supported.
     */
    public int getMaxSize() {
        return mMaxSize;
    }

    /**
     * Retrieves the minimum duration supported between two control points within an envelope
     * effect, in milliseconds.
     *
     * <p>If the device supports envelope effects
     * (check {@link android.os.VibratorInfo#areEnvelopeEffectsSupported}), this value will be
     * positive. Devices with envelope effects capabilities guarantee support for durations down
     * to at least 20 milliseconds. If the device does not support envelope effects,
     * this method will return 0.
     *
     * @return the minimum allowed duration between two control points in an envelope effect,
     * or 0 if envelope effects are not supported.
     */
    public long getMinControlPointDurationMillis() {
        return mMinControlPointDurationMillis;
    }

    /**
     * Retrieves the maximum duration supported between two control points within an envelope
     * effect, in milliseconds.
     *
     * <p>If the device supports envelope effects
     * (check {@link android.os.VibratorInfo#areEnvelopeEffectsSupported}), this value will be
     * positive. Devices with envelope effects capabilities guarantee support for durations up to
     * at least 1 second. If the device does not support envelope effects, this method
     * will return 0.
     *
     * @return the maximum allowed duration between two control points in an envelope effect,
     * or 0 if envelope effects are not supported.
     */
    public long getMaxControlPointDurationMillis() {
        return mMaxControlPointDurationMillis;
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -44,7 +44,7 @@ final class SplitPwleSegmentsAdapter implements VibrationSegmentsAdapter {
            // The vibrator does not have PWLE v2 capability, so keep the segments unchanged.
            return repeatIndex;
        }
        int maxPwleDuration = info.getMaxEnvelopeEffectDurationMillis();
        int maxPwleDuration = (int) info.getMaxEnvelopeEffectDurationMillis();
        if (maxPwleDuration <= 0) {
            // No limit set to PWLE primitive duration.
            return repeatIndex;
+1 −1

File changed.

Contains only whitespace changes.

Loading