Merge "Allow blocking transaction to IExternalVibrationController"

This commit is contained in:
TreeHugger Robot
2021-09-01 12:17:04 +00:00
committed by Android (Google) Code Review
3 changed files with 24 additions and 12 deletions

View File

@@ -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();

View File

@@ -1380,8 +1380,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.

View File

@@ -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());
}