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

Commit 81b89373 authored by Lais Andrade's avatar Lais Andrade
Browse files

Allow blocking transaction to IExternalVibrationController

Clear android stability warnings for calls to mute/unmute the external
vibration controlled by the audio framework via the
IExternalVibrationController implementation.

Fix: 197793087
Test: N/A
Change-Id: Ife1c8e59bfe5764316da8eb8b32fc054be7ff213
parent 5e723f76
Loading
Loading
Loading
Loading
+21 −8
Original line number Diff line number Diff line
@@ -42,25 +42,38 @@ public class ExternalVibration implements Parcelable {
    // boundaries.
    @NonNull
    private IBinder mToken;

    public ExternalVibration(int uid, @NonNull String pkg, @NonNull AudioAttributes attrs,
            @NonNull IExternalVibrationController controller) {
        this(uid, pkg, attrs, controller, new Binder());
    }

    private ExternalVibration(int uid, @NonNull String pkg, @NonNull AudioAttributes attrs,
            @NonNull IExternalVibrationController controller, @NonNull IBinder token) {
        mUid = uid;
        mPkg = Preconditions.checkNotNull(pkg);
        mAttrs = Preconditions.checkNotNull(attrs);
        mController = Preconditions.checkNotNull(controller);
        mToken = new Binder();
        mToken = Preconditions.checkNotNull(token);

        // IExternalVibrationController is a hidden AIDL interface with implementation provided by
        // the audio framework to allow mute/unmute control over the external vibration.
        //
        // Transactions are locked in audioflinger, and should be blocking to avoid racing
        // conditions on multiple audio playback.
        //
        // They can also be triggered before starting a new external vibration in
        // IExternalVibratorService, as the ongoing external vibration needs to be muted before the
        // new one can start, which also requires blocking calls to mute.
        Binder.allowBlocking(mController.asBinder());
    }

    private ExternalVibration(Parcel in) {
        mUid = in.readInt();
        mPkg = in.readString();
        mAttrs = readAudioAttributes(in);
        mController = IExternalVibrationController.Stub.asInterface(in.readStrongBinder());
        mToken = in.readStrongBinder();
        this(in.readInt(), in.readString(), readAudioAttributes(in),
                IExternalVibrationController.Stub.asInterface(in.readStrongBinder()),
                in.readStrongBinder());
    }

    private AudioAttributes readAudioAttributes(Parcel in) {
    private static AudioAttributes readAudioAttributes(Parcel in) {
        int usage = in.readInt();
        int contentType = in.readInt();
        int capturePreset = in.readInt();
+2 −2
Original line number Diff line number Diff line
@@ -1355,8 +1355,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
                    // At this point we have an externally controlled vibration playing already.
                    // Since the interface defines that only one externally controlled vibration can
                    // play at a time, we need to first mute the ongoing vibration and then return
                    // a scale from this function for the new one. Ee can be assured that the
                    // ongoing it will be muted in favor of the new vibration.
                    // a scale from this function for the new one, so we can be assured that the
                    // ongoing will be muted in favor of the new vibration.
                    //
                    // Note that this doesn't support multiple concurrent external controls, as we
                    // would need to mute the old one still if it came from a different controller.
+1 −2
Original line number Diff line number Diff line
@@ -35,7 +35,6 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;

import android.app.AppOpsManager;
@@ -1016,7 +1015,7 @@ public class VibratorManagerServiceTest {
        assertEquals(IExternalVibratorService.SCALE_NONE, firstScale);
        assertEquals(IExternalVibratorService.SCALE_NONE, secondScale);
        verify(firstController).mute();
        verifyNoMoreInteractions(secondController);
        verify(secondController, never()).mute();
        // Set external control called only once.
        assertEquals(Arrays.asList(true), mVibratorProviders.get(1).getExternalControlStates());
    }