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

Commit 02153e69 authored by Eric Laurent's avatar Eric Laurent
Browse files

audioservice: special mute behavior for BT SCO volume

Allow muting BT SCO volume only from explicit mute request and not
when stream volume index is set to 0. This is to match BT requirement
that the valid SCO volume range is 0 to 15 and let the headset deal with
actual attenuation for index 0.
If explicitly muted via adjustStreamVolume() from an app with permission
MODIFY_PHONE_STATE, then we set the audio policy stream volume to 0 and
effectively mute RX path.

Also change default value of Settings.System.MUTE_STREAMS_AFFECTED
to include AudioManager.STREAM_BLUETOOTH_SCO.

Bug: 111195322
Test: test volume changes in call over BT SCO
Change-Id: I3b6560bbd1bcbb01a29aa746f23bae74329a1fa7
parent fcbde524
Loading
Loading
Loading
Loading
+32 −1
Original line number Diff line number Diff line
@@ -3238,7 +3238,7 @@ public class SettingsProvider extends ContentProvider {
        }

        private final class UpgradeController {
            private static final int SETTINGS_VERSION = 181;
            private static final int SETTINGS_VERSION = 182;

            private final int mUserId;

@@ -4421,6 +4421,37 @@ public class SettingsProvider extends ContentProvider {
                    currentVersion = 181;
                }

                if (currentVersion == 181) {
                    // Version cd : by default, add STREAM_BLUETOOTH_SCO to list of streams that can
                    // be muted.
                    final SettingsState systemSettings = getSystemSettingsLocked(userId);
                    final Setting currentSetting = systemSettings.getSettingLocked(
                              Settings.System.MUTE_STREAMS_AFFECTED);
                    if (!currentSetting.isNull()) {
                        try {
                            int currentSettingIntegerValue = Integer.parseInt(
                                    currentSetting.getValue());
                            if ((currentSettingIntegerValue
                                    & (1 << AudioManager.STREAM_BLUETOOTH_SCO)) == 0) {
                                systemSettings.insertSettingLocked(
                                        Settings.System.MUTE_STREAMS_AFFECTED,
                                        Integer.toString(
                                        currentSettingIntegerValue
                                        | (1 << AudioManager.STREAM_BLUETOOTH_SCO)),
                                        null, true, SettingsState.SYSTEM_PACKAGE_NAME);
                            }
                        } catch (NumberFormatException e) {
                            // remove the setting in case it is not a valid integer
                            Slog.w("Failed to parse integer value of MUTE_STREAMS_AFFECTED"
                                    + "setting, removing setting", e);
                            systemSettings.deleteSettingLocked(
                                    Settings.System.MUTE_STREAMS_AFFECTED);
                        }

                    }
                    currentVersion = 182;
                }

                // vXXX: Add new settings above this point.

                if (currentVersion != newVersion) {
+22 −13
Original line number Diff line number Diff line
@@ -2052,9 +2052,12 @@ public class AudioService extends IAudioService.Stub
            setRingerMode(getNewRingerMode(stream, index, flags),
                    TAG + ".onSetStreamVolume", false /*external*/);
        }
        // setting non-zero volume for a muted stream unmutes the stream and vice versa
        // setting non-zero volume for a muted stream unmutes the stream and vice versa,
        // except for BT SCO stream where only explicit mute is allowed to comply to BT requirements
        if (streamType != AudioSystem.STREAM_BLUETOOTH_SCO) {
            mStreamStates[stream].mute(index == 0);
        }
    }

    private void enforceModifyAudioRoutingPermission() {
        if (mContext.checkCallingPermission(
@@ -2131,14 +2134,11 @@ public class AudioService extends IAudioService.Stub
                    + " CHANGE_ACCESSIBILITY_VOLUME  callingPackage=" + callingPackage);
            return;
        }
        if ((streamType == AudioManager.STREAM_VOICE_CALL ||
                streamType == AudioManager.STREAM_BLUETOOTH_SCO) &&
                (index == 0) &&
                (mContext.checkCallingOrSelfPermission(
        if ((streamType == AudioManager.STREAM_VOICE_CALL) && (index == 0)
                && (mContext.checkCallingOrSelfPermission(
                    android.Manifest.permission.MODIFY_PHONE_STATE)
                    != PackageManager.PERMISSION_GRANTED)) {
            Log.w(TAG, "Trying to call setStreamVolume() for STREAM_VOICE_CALL or"
                    + " STREAM_BLUETOOTH_SCO and index 0 without"
            Log.w(TAG, "Trying to call setStreamVolume() for STREAM_VOICE_CALL and index 0 without"
                    + " MODIFY_PHONE_STATE  callingPackage=" + callingPackage);
            return;
        }
@@ -4641,6 +4641,16 @@ public class AudioService extends IAudioService.Stub
            return index;
        }

        private void setStreamVolumeIndex(int index, int device) {
            // Only set audio policy BT SCO stream volume to 0 when the stream is actually muted.
            // This allows RX path muting by the audio HAL only when explicitly muted but not when
            // index is just set to 0 to repect BT requirements
            if (mStreamType == AudioSystem.STREAM_BLUETOOTH_SCO && index == 0 && !mIsMuted) {
                index = 1;
            }
            AudioSystem.setStreamVolumeIndexAS(mStreamType, index, device);
        }

        // must be called while synchronized VolumeStreamState.class
        /*package*/ void applyDeviceVolume_syncVSS(int device, boolean isAvrcpAbsVolSupported) {
            int index;
@@ -4655,7 +4665,7 @@ public class AudioService extends IAudioService.Stub
            } else {
                index = (getIndex(device) + 5)/10;
            }
            AudioSystem.setStreamVolumeIndexAS(mStreamType, index, device);
            setStreamVolumeIndex(index, device);
        }

        public void applyAllVolumes() {
@@ -4678,7 +4688,7 @@ public class AudioService extends IAudioService.Stub
                        } else {
                            index = (mIndexMap.valueAt(i) + 5)/10;
                        }
                        AudioSystem.setStreamVolumeIndexAS(mStreamType, index, device);
                        setStreamVolumeIndex(index, device);
                    }
                }
                // apply default volume last: by convention , default device volume will be used
@@ -4688,8 +4698,7 @@ public class AudioService extends IAudioService.Stub
                } else {
                    index = (getIndex(AudioSystem.DEVICE_OUT_DEFAULT) + 5)/10;
                }
                AudioSystem.setStreamVolumeIndexAS(
                        mStreamType, index, AudioSystem.DEVICE_OUT_DEFAULT);
                setStreamVolumeIndex(index, AudioSystem.DEVICE_OUT_DEFAULT);
            }
        }