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

Commit eda9495c authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add FLAG_PIPELINED_EFFECT to VibrationAttributes."

parents 49bd302a 8822d4c9
Loading
Loading
Loading
Loading
+18 −5
Original line number Diff line number Diff line
@@ -146,7 +146,8 @@ public final class VibrationAttributes implements Parcelable {
    @IntDef(prefix = { "FLAG_" }, flag = true, value = {
            FLAG_BYPASS_INTERRUPTION_POLICY,
            FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF,
            FLAG_INVALIDATE_SETTINGS_CACHE
            FLAG_INVALIDATE_SETTINGS_CACHE,
            FLAG_PIPELINED_EFFECT
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface Flag{}
@@ -157,7 +158,7 @@ public final class VibrationAttributes implements Parcelable {
     * <p>Only privileged apps can ignore user settings that limit interruptions, and this
     * flag will be ignored otherwise.
     */
    public static final int FLAG_BYPASS_INTERRUPTION_POLICY = 0x1;
    public static final int FLAG_BYPASS_INTERRUPTION_POLICY = 1;

    /**
     * Flag requesting vibration effect to be played even when user settings are disabling it.
@@ -168,7 +169,7 @@ public final class VibrationAttributes implements Parcelable {
     *
     * @hide
     */
    public static final int FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF = 0x2;
    public static final int FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF = 1 << 1;

    /**
     * Flag requesting vibration effect to be played with fresh user settings values.
@@ -183,7 +184,19 @@ public final class VibrationAttributes implements Parcelable {
     *
     * @hide
     */
    public static final int FLAG_INVALIDATE_SETTINGS_CACHE = 0x4;
    public static final int FLAG_INVALIDATE_SETTINGS_CACHE = 1 << 2;

    /**
     * Flag requesting that this vibration effect be pipelined with other vibration effects from the
     * same package that also carry this flag.
     *
     * <p>Pipelined effects won't cancel a running pipelined effect, but will instead play after
     * it completes. However, only one pipelined effect can be waiting at a time - so if an effect
     * is already waiting (but not running), it will be cancelled in favor of a newer one.
     *
     * @hide
     */
    public static final int FLAG_PIPELINED_EFFECT = 1 << 3;

    /**
     * All flags supported by vibrator service, update it when adding new flag.
@@ -191,7 +204,7 @@ public final class VibrationAttributes implements Parcelable {
     */
    public static final int FLAG_ALL_SUPPORTED =
            FLAG_BYPASS_INTERRUPTION_POLICY | FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF
                    | FLAG_INVALIDATE_SETTINGS_CACHE;
                    | FLAG_INVALIDATE_SETTINGS_CACHE | FLAG_PIPELINED_EFFECT;

    /** Creates a new {@link VibrationAttributes} instance with given usage. */
    public static @NonNull VibrationAttributes createForUsage(@Usage int usage) {
+14 −0
Original line number Diff line number Diff line
@@ -251,6 +251,20 @@ final class Vibration {
                uid, vibrationType, attrs.getUsage(), mStatus, mStats, completionUptimeMillis);
    }

    /**
     * Returns true if this vibration can pipeline with the specified one.
     *
     * <p>Note that currently, repeating vibrations can't pipeline with following vibrations,
     * because the cancel() call to stop the repetition will cancel a pending vibration too. This
     * can be changed if we have a use-case to reason around behavior for. It may also be nice to
     * pipeline very short vibrations together, regardless of the flag.
     */
    public boolean canPipelineWith(Vibration vib) {
        return uid == vib.uid && attrs.isFlagSet(VibrationAttributes.FLAG_PIPELINED_EFFECT)
                && vib.attrs.isFlagSet(VibrationAttributes.FLAG_PIPELINED_EFFECT)
                && !isRepeating();
    }

    /** Immutable info passed as a signal to end a vibration. */
    static final class EndInfo {
        /** The {@link Status} to be set to the vibration when it ends with this info. */
+8 −0
Original line number Diff line number Diff line
@@ -281,6 +281,14 @@ final class VibrationStepConductor implements IBinder.DeathRecipient {
        // to run it before processing callbacks as the window is tiny.
        Step nextStep = pollNext();
        if (nextStep != null) {
            if (DEBUG) {
                Slog.d(TAG, "Playing vibration id " + getVibration().id
                        + ((nextStep instanceof AbstractVibratorStep)
                        ? " on vibrator " + ((AbstractVibratorStep) nextStep).getVibratorId() : "")
                        + " " + nextStep.getClass().getSimpleName()
                        + (nextStep.isCleanUp() ? " (cleanup)" : ""));
            }

            List<Step> nextSteps = nextStep.play();
            if (nextStep.getVibratorOnDuration() > 0) {
                mSuccessfulVibratorOnSteps++;
+0 −3
Original line number Diff line number Diff line
@@ -292,9 +292,6 @@ final class VibrationThread extends Thread {
                boolean readyToRun = mExecutingConductor.waitUntilNextStepIsDue();
                // If we waited, don't run the next step, but instead re-evaluate status.
                if (readyToRun) {
                    if (DEBUG) {
                        Slog.d(TAG, "Play vibration consuming next step...");
                    }
                    // Run the step without holding the main lock, to avoid HAL interactions from
                    // blocking the thread.
                    mExecutingConductor.runNextStep();
+24 −8
Original line number Diff line number Diff line
@@ -450,6 +450,15 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
                    final long ident = Binder.clearCallingIdentity();
                    try {
                        if (mCurrentVibration != null) {
                            if (mCurrentVibration.getVibration().canPipelineWith(vib)) {
                                // Don't cancel the current vibration if it's pipeline-able.
                                // Note that if there is a pending next vibration that can't be
                                // pipelined, it will have already cancelled the current one, so we
                                // don't need to consider it here as well.
                                if (DEBUG) {
                                    Slog.d(TAG, "Pipelining vibration " + vib.id);
                                }
                            } else {
                                vib.stats().reportInterruptedAnotherVibration(
                                        mCurrentVibration.getVibration().attrs.getUsage());
                                mCurrentVibration.notifyCancelled(
@@ -458,6 +467,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
                                                vib.attrs.getUsage()),
                                        /* immediate= */ false);
                            }
                        }
                        status = startVibrationLocked(vib);
                    } finally {
                        Binder.restoreCallingIdentity(ident);
@@ -690,6 +700,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
            }
            // If there's already a vibration queued (waiting for the previous one to finish
            // cancelling), end it cleanly and replace it with the new one.
            // Note that we don't consider pipelining here, because new pipelined ones should
            // replace pending non-executing pipelined ones anyway.
            clearNextVibrationLocked(
                    new Vibration.EndInfo(Vibration.Status.IGNORED_SUPERSEDED,
                            vib.uid, vib.attrs.getUsage()));
@@ -1594,6 +1606,10 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
    @GuardedBy("mLock")
    private void clearNextVibrationLocked(Vibration.EndInfo vibrationEndInfo) {
        if (mNextVibration != null) {
            if (DEBUG) {
                Slog.d(TAG, "Dropping pending vibration " + mNextVibration.getVibration().id
                        + " with end info: " + vibrationEndInfo);
            }
            // Clearing next vibration before playing it, end it and report metrics right away.
            endVibrationLocked(mNextVibration.getVibration(), vibrationEndInfo,
                    /* shouldWriteStats= */ true);
Loading