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

Commit 42cdae92 authored by Lais Andrade's avatar Lais Andrade Committed by Android (Google) Code Review
Browse files

Merge "Unify current session in vibrator service" into main

parents c71086f4 8e1c638b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -158,7 +158,6 @@ message VibratorManagerServiceDumpProto {
    repeated int32 vibrator_ids = 1;
    optional VibrationProto current_vibration = 2;
    optional int32 is_vibrator_controller_registered = 27;
    optional VibrationProto current_external_vibration = 4;
    optional bool low_power_mode = 6;
    optional bool vibrate_on = 24;
    reserved 25; // prev keyboard_vibration_on
@@ -183,4 +182,5 @@ message VibratorManagerServiceDumpProto {
    reserved 17; // prev previous_external_vibrations
    reserved 3; // prev is_vibrating, check current_vibration instead
    reserved 5; // prev vibrator_under_external_control, check current_external_vibration instead
    reserved 4; // prev current_external_vibration, check current_vibration instead
}
 No newline at end of file
+33 −23
Original line number Diff line number Diff line
@@ -24,8 +24,8 @@ import android.os.ExternalVibrationScale;
import android.os.IBinder;
import android.os.VibrationAttributes;
import android.os.vibrator.Flags;
import android.util.Slog;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.FrameworkStatsLog;

/**
@@ -33,22 +33,31 @@ import com.android.internal.util.FrameworkStatsLog;
 */
final class ExternalVibrationSession extends Vibration
        implements VibrationSession, IBinder.DeathRecipient {
    private static final String TAG = "ExternalVibrationSession";

    /** Calls into VibratorManager functionality needed for playing an {@link ExternalVibration}. */
    interface VibratorManagerHooks {

        /**
         * Tells the manager that the external vibration is finished and the vibrators can now be
         * used for another vibration.
         */
        void onExternalVibrationReleased(long vibrationId);
    }

    private final Object mLock = new Object();
    private final ExternalVibration mExternalVibration;
    private final ExternalVibrationScale mScale = new ExternalVibrationScale();
    private final VibratorManagerHooks mManagerHooks;

    @GuardedBy("mLock")
    @Nullable
    private Runnable mBinderDeathCallback;

    ExternalVibrationSession(ExternalVibration externalVibration) {
    ExternalVibrationSession(ExternalVibration externalVibration,
            VibratorManagerHooks managerHooks) {
        super(new CallerInfo(
                externalVibration.getVibrationAttributes(), externalVibration.getUid(),
                // TODO(b/249785241): Find a way to link ExternalVibration to a VirtualDevice
                // instead of using DEVICE_ID_INVALID here and relying on the UID checks.
                Context.DEVICE_ID_INVALID, externalVibration.getPackage(), null));
        mExternalVibration = externalVibration;
        mManagerHooks = managerHooks;
    }

    public ExternalVibrationScale getScale() {
@@ -94,10 +103,7 @@ final class ExternalVibrationSession extends Vibration
    }

    @Override
    public boolean linkToDeath(Runnable callback) {
        synchronized (mLock) {
            mBinderDeathCallback = callback;
        }
    public boolean linkToDeath() {
        mExternalVibration.linkToDeath(this);
        return true;
    }
@@ -105,39 +111,33 @@ final class ExternalVibrationSession extends Vibration
    @Override
    public void unlinkToDeath() {
        mExternalVibration.unlinkToDeath(this);
        synchronized (mLock) {
            mBinderDeathCallback = null;
        }
    }

    @Override
    public void binderDied() {
        Runnable callback;
        synchronized (mLock) {
            callback = mBinderDeathCallback;
        }
        if (callback != null) {
            callback.run();
        }
        Slog.d(TAG, "Binder died, cancelling external vibration...");
        requestEnd(Status.CANCELLED_BINDER_DIED);
    }

    @Override
    void end(EndInfo endInfo) {
        super.end(endInfo);
        if (stats.hasStarted()) {
            // Notify external client that this vibration should stop sending data to the vibrator.
            mExternalVibration.mute();
            // External vibration doesn't have feedback from total time the vibrator was playing
            // with non-zero amplitude, so we use the duration between start and end times of
            // the vibration as the time the vibrator was ON, since the haptic channels are
            // open for this duration and can receive vibration waveform data.
            stats.reportVibratorOn(stats.getEndUptimeMillis() - stats.getStartUptimeMillis());
            // Notify the manager that external client has released the vibrator control.
            mManagerHooks.onExternalVibrationReleased(id);
        }
    }

    @Override
    public void requestEnd(@NonNull Status status, @Nullable CallerInfo endedBy,
            boolean immediate) {
        // Notify external client that this vibration should stop sending data to the vibrator.
        mExternalVibration.mute();
        end(new EndInfo(status, endedBy));
    }

@@ -170,4 +170,14 @@ final class ExternalVibrationSession extends Vibration
        mScale.adaptiveHapticsScale = scaler.getAdaptiveHapticsScale(usage);
        stats.reportAdaptiveScale(mScale.adaptiveHapticsScale);
    }

    @Override
    public String toString() {
        return "ExternalVibrationSession{"
                + "id=" + id
                + ", callerInfo=" + callerInfo
                + ", externalVibration=" + mExternalVibration
                + ", scale=" + mScale
                + '}';
    }
}
+9 −18
Original line number Diff line number Diff line
@@ -41,10 +41,6 @@ final class SingleVibrationSession implements VibrationSession, IBinder.DeathRec
    @GuardedBy("mLock")
    private VibrationStepConductor mConductor;

    @GuardedBy("mLock")
    @Nullable
    private Runnable mBinderDeathCallback;

    SingleVibrationSession(@NonNull IBinder callerToken, @NonNull CallerInfo callerInfo,
            @NonNull CombinedVibration vibration) {
        mCallerToken = callerToken;
@@ -100,20 +96,10 @@ final class SingleVibrationSession implements VibrationSession, IBinder.DeathRec
    public void binderDied() {
        Slog.d(TAG, "Binder died, cancelling vibration...");
        requestEnd(Status.CANCELLED_BINDER_DIED, /* endedBy= */ null, /* immediate= */ false);
        Runnable callback;
        synchronized (mLock) {
            callback = mBinderDeathCallback;
        }
        if (callback != null) {
            callback.run();
        }
    }

    @Override
    public boolean linkToDeath(@Nullable Runnable callback) {
        synchronized (mLock) {
            mBinderDeathCallback = callback;
        }
    public boolean linkToDeath() {
        try {
            mCallerToken.linkToDeath(this, 0);
        } catch (RemoteException e) {
@@ -130,9 +116,6 @@ final class SingleVibrationSession implements VibrationSession, IBinder.DeathRec
        } catch (NoSuchElementException e) {
            Slog.wtf(TAG, "Failed to unlink vibration to token death", e);
        }
        synchronized (mLock) {
            mBinderDeathCallback = null;
        }
    }

    @Override
@@ -170,4 +153,12 @@ final class SingleVibrationSession implements VibrationSession, IBinder.DeathRec
            }
        }
    }

    @Override
    public String toString() {
        return "SingleVibrationSession{"
                + "callerToken= " + mCallerToken
                + ", vibration=" + mVibration
                + '}';
    }
}
+2 −9
Original line number Diff line number Diff line
@@ -54,15 +54,8 @@ interface VibrationSession {
    /** Returns debug data for logging and metric reports. */
    DebugInfo getDebugInfo();

    /**
     * Links this session to the app process death with given callback to handle it.
     *
     * <p>This can be used by the service to end the vibration session when the app process dies.
     *
     * @param callback The service callback to be triggered when the binder dies
     * @return true if the link was successful, false otherwise
     */
    boolean linkToDeath(@Nullable Runnable callback);
    /** Links this session to the app process death, returning false if link failed. */
    boolean linkToDeath();

    /** Removes link to the app process death. */
    void unlinkToDeath();
+207 −169

File changed.

Preview size limit exceeded, changes collapsed.

Loading