diff options
3 files changed, 40 insertions, 10 deletions
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java index 1dc1846fbb96..6203977dc877 100644 --- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java +++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java @@ -15,6 +15,8 @@ */ package com.android.server.audio; +import static android.media.audio.Flags.scoManagedByAudio; + import android.annotation.NonNull; import android.annotation.Nullable; import android.app.compat.CompatChanges; @@ -54,6 +56,7 @@ import android.os.RemoteException; import android.os.SystemClock; import android.os.UserHandle; import android.provider.Settings; +import android.sysprop.BluetoothProperties; import android.text.TextUtils; import android.util.Log; import android.util.Pair; @@ -74,7 +77,6 @@ import java.util.Objects; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; - /** * @hide * (non final for mocking/spying) @@ -167,6 +169,15 @@ public class AudioDeviceBroker { @EnabledSince(targetSdkVersion = android.os.Build.VERSION_CODES.S_V2) public static final long USE_SET_COMMUNICATION_DEVICE = 243827847L; + /** Indicates if headset profile connection and SCO audio control use the new implementation + * aligned with other BT profiles. True if both the feature flag Flags.scoManagedByAudio() and + * the system property audio.sco.managed.by.audio are true. + */ + private final boolean mScoManagedByAudio; + /*package*/ boolean isScoManagedByAudio() { + return mScoManagedByAudio; + } + //------------------------------------------------------------------- /*package*/ AudioDeviceBroker(@NonNull Context context, @NonNull AudioService service, @NonNull AudioSystemAdapter audioSystem) { @@ -176,7 +187,8 @@ public class AudioDeviceBroker { mDeviceInventory = new AudioDeviceInventory(this); mSystemServer = SystemServerAdapter.getDefaultAdapter(mContext); mAudioSystem = audioSystem; - + mScoManagedByAudio = scoManagedByAudio() + && BluetoothProperties.isScoManagedByAudioEnabled().orElse(false); init(); } @@ -192,7 +204,8 @@ public class AudioDeviceBroker { mDeviceInventory = mockDeviceInventory; mSystemServer = mockSystemServer; mAudioSystem = audioSystem; - + mScoManagedByAudio = scoManagedByAudio() + && BluetoothProperties.isScoManagedByAudioEnabled().orElse(false); init(); } @@ -1685,6 +1698,8 @@ public class AudioDeviceBroker { pw.println("\n" + prefix + "mAudioModeOwner: " + mAudioModeOwner); + pw.println("\n" + prefix + "mScoManagedByAudio: " + mScoManagedByAudio); + mBtHelper.dump(pw, prefix); } @@ -1837,10 +1852,10 @@ public class AudioDeviceBroker { ? mAudioService.getBluetoothContextualVolumeStream() : AudioSystem.STREAM_DEFAULT); if (btInfo.mProfile == BluetoothProfile.LE_AUDIO - || btInfo.mProfile - == BluetoothProfile.HEARING_AID) { - onUpdateCommunicationRouteClient( - isBluetoothScoRequested(), + || btInfo.mProfile == BluetoothProfile.HEARING_AID + || (mScoManagedByAudio + && btInfo.mProfile == BluetoothProfile.HEADSET)) { + onUpdateCommunicationRouteClient(isBluetoothScoRequested(), "setBluetoothActiveDevice"); } } @@ -2815,4 +2830,5 @@ public class AudioDeviceBroker { void clearDeviceInventory() { mDeviceInventory.clearDeviceInventory(); } + } diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java index e0790da7cd09..287c92f86f0f 100644 --- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java +++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java @@ -859,6 +859,15 @@ public class AudioDeviceInventory { btInfo, streamType, codec, "onSetBtActiveDevice"); } break; + case BluetoothProfile.HEADSET: + if (mDeviceBroker.isScoManagedByAudio()) { + if (switchToUnavailable) { + mDeviceBroker.onSetBtScoActiveDevice(null); + } else if (switchToAvailable) { + mDeviceBroker.onSetBtScoActiveDevice(btInfo.mDevice); + } + } + break; default: throw new IllegalArgumentException("Invalid profile " + BluetoothProfile.getProfileName(btInfo.mProfile)); } diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index baa7f2f389e8..220f2b96eddf 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -48,6 +48,7 @@ import static android.media.audio.Flags.automaticBtDeviceType; import static android.media.audio.Flags.featureSpatialAudioHeadtrackingLowLatency; import static android.media.audio.Flags.focusFreezeTestApi; import static android.media.audio.Flags.roForegroundAudioControl; +import static android.media.audio.Flags.scoManagedByAudio; import static android.media.audiopolicy.Flags.enableFadeManagerConfiguration; import static android.os.Process.FIRST_APPLICATION_UID; import static android.os.Process.INVALID_UID; @@ -1503,7 +1504,9 @@ public class AudioService extends IAudioService.Stub // Register for device connection intent broadcasts. IntentFilter intentFilter = new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED); - intentFilter.addAction(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED); + if (!mDeviceBroker.isScoManagedByAudio()) { + intentFilter.addAction(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED); + } intentFilter.addAction(Intent.ACTION_DOCK_EVENT); if (mDisplayManager == null) { intentFilter.addAction(Intent.ACTION_SCREEN_ON); @@ -4528,11 +4531,12 @@ public class AudioService extends IAudioService.Stub + focusFreezeTestApi()); pw.println("\tcom.android.media.audio.disablePrescaleAbsoluteVolume:" + disablePrescaleAbsoluteVolume()); - pw.println("\tcom.android.media.audio.setStreamVolumeOrder:" + setStreamVolumeOrder()); pw.println("\tandroid.media.audio.roForegroundAudioControl:" + roForegroundAudioControl()); + pw.println("\tandroid.media.audio.scoManagedByAudio:" + + scoManagedByAudio()); pw.println("\tcom.android.media.audio.vgsVssSyncMuteOrder:" + vgsVssSyncMuteOrder()); } @@ -7858,7 +7862,8 @@ public class AudioService extends IAudioService.Stub if (profile != BluetoothProfile.A2DP && profile != BluetoothProfile.A2DP_SINK && profile != BluetoothProfile.LE_AUDIO && profile != BluetoothProfile.LE_AUDIO_BROADCAST - && profile != BluetoothProfile.HEARING_AID) { + && profile != BluetoothProfile.HEARING_AID + && !(mDeviceBroker.isScoManagedByAudio() && profile == BluetoothProfile.HEADSET)) { throw new IllegalArgumentException("Illegal BluetoothProfile profile for device " + previousDevice + " -> " + newDevice + ". Got: " + profile); } |