audio: additional speakerphone and audio mode fixes

- Do not re-evaluate speakerphone state when audio mode owner
changes but the new mode is RINGTONE.
- Do not log IN_COMMUNICATION mode timeout in case of playback or
capture inactivity by mode owner if the owner has
MODIFY_PHONE_STATE permission: in this case it is the telephony framework
or the app in Dialer role managing the call on behalf of another app.

Bug: 161564483
Test: manual regression test with cell and VoIP calls.
Change-Id: I86b6d31a164461e143cc5cfc1369884ed14cc95a
This commit is contained in:
Eric Laurent
2020-08-13 11:52:50 -07:00
parent 0beeb34e5c
commit 1536fc19e5
2 changed files with 24 additions and 13 deletions

View File

@@ -499,8 +499,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
sendIIMsgNoDelay(MSG_II_SET_HEARING_AID_VOLUME, SENDMSG_REPLACE, index, streamType);
}
/*package*/ void postSetModeOwnerPid(int pid) {
sendIMsgNoDelay(MSG_I_SET_MODE_OWNER_PID, SENDMSG_REPLACE, pid);
/*package*/ void postSetModeOwnerPid(int pid, int mode) {
sendIIMsgNoDelay(MSG_I_SET_MODE_OWNER_PID, SENDMSG_REPLACE, pid, mode);
}
/*package*/ void postBluetoothA2dpDeviceConfigChange(@NonNull BluetoothDevice device) {
@@ -976,7 +976,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
synchronized (mDeviceStateLock) {
if (mModeOwnerPid != msg.arg1) {
mModeOwnerPid = msg.arg1;
updateSpeakerphoneOn("setNewModeOwner");
if (msg.arg2 != AudioSystem.MODE_RINGTONE) {
updateSpeakerphoneOn("setNewModeOwner");
}
if (mModeOwnerPid != 0) {
mBtHelper.disconnectBluetoothSco(mModeOwnerPid);
}

View File

@@ -3713,13 +3713,15 @@ public class AudioService extends IAudioService.Stub
private final IBinder mCb; // To be notified of client's death
private final int mPid;
private final int mUid;
private String mPackage;
private final boolean mIsPrivileged;
private final String mPackage;
private int mMode = AudioSystem.MODE_NORMAL; // Current mode set by this client
SetModeDeathHandler(IBinder cb, int pid, int uid, String caller) {
SetModeDeathHandler(IBinder cb, int pid, int uid, boolean isPrivileged, String caller) {
mCb = cb;
mPid = pid;
mUid = uid;
mIsPrivileged = isPrivileged;
mPackage = caller;
}
@@ -3731,12 +3733,13 @@ public class AudioService extends IAudioService.Stub
if (index < 0) {
Log.w(TAG, "unregistered setMode() client died");
} else {
newModeOwnerPid = setModeInt(AudioSystem.MODE_NORMAL, mCb, mPid, mUid, TAG);
newModeOwnerPid = setModeInt(
AudioSystem.MODE_NORMAL, mCb, mPid, mUid, mIsPrivileged, TAG);
}
}
// when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all
// SCO connections not started by the application changing the mode when pid changes
mDeviceBroker.postSetModeOwnerPid(newModeOwnerPid);
mDeviceBroker.postSetModeOwnerPid(newModeOwnerPid, AudioService.this.getMode());
}
public int getPid() {
@@ -3762,6 +3765,10 @@ public class AudioService extends IAudioService.Stub
public String getPackage() {
return mPackage;
}
public boolean isPrivileged() {
return mIsPrivileged;
}
}
/** @see AudioManager#setMode(int) */
@@ -3813,18 +3820,19 @@ public class AudioService extends IAudioService.Stub
+ " without permission or being mode owner");
return;
}
newModeOwnerPid = setModeInt(
mode, cb, callingPid, Binder.getCallingUid(), callingPackage);
newModeOwnerPid = setModeInt(mode, cb, callingPid, Binder.getCallingUid(),
hasModifyPhoneStatePermission, callingPackage);
}
// when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all
// SCO connections not started by the application changing the mode when pid changes
mDeviceBroker.postSetModeOwnerPid(newModeOwnerPid);
mDeviceBroker.postSetModeOwnerPid(newModeOwnerPid, getMode());
}
// setModeInt() returns a valid PID if the audio mode was successfully set to
// any mode other than NORMAL.
@GuardedBy("mDeviceBroker.mSetModeLock")
private int setModeInt(int mode, IBinder cb, int pid, int uid, String caller) {
private int setModeInt(
int mode, IBinder cb, int pid, int uid, boolean isPrivileged, String caller) {
if (DEBUG_MODE) {
Log.v(TAG, "setModeInt(mode=" + mode + ", pid=" + pid
+ ", uid=" + uid + ", caller=" + caller + ")");
@@ -3876,7 +3884,7 @@ public class AudioService extends IAudioService.Stub
}
} else {
if (hdlr == null) {
hdlr = new SetModeDeathHandler(cb, pid, uid, caller);
hdlr = new SetModeDeathHandler(cb, pid, uid, isPrivileged, caller);
}
// Register for client death notification
try {
@@ -3935,7 +3943,8 @@ public class AudioService extends IAudioService.Stub
// change of mode may require volume to be re-applied on some devices
updateAbsVolumeMultiModeDevices(oldMode, actualMode);
if (actualMode == AudioSystem.MODE_IN_COMMUNICATION) {
if (actualMode == AudioSystem.MODE_IN_COMMUNICATION
&& !hdlr.isPrivileged()) {
sendMsg(mAudioHandler,
MSG_CHECK_MODE_FOR_UID,
SENDMSG_QUEUE,