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

Commit a7391758 authored by Jack He's avatar Jack He Committed by Gerrit Code Review
Browse files

Merge "Broadcast active device only when Audio Fwk update AudioDevices" into main

parents 7ed0ae8f 7560a528
Loading
Loading
Loading
Loading
+125 −15
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioDeviceCallback;
import android.media.AudioDeviceInfo;
import android.media.AudioManager;
import android.media.BluetoothProfileConnectionInfo;
@@ -141,6 +142,7 @@ public class HeadsetService extends ProfileService {
    private final HeadsetSystemInterface mSystemInterface;

    private int mMaxHeadsetConnections = 1;
    private BluetoothDevice mExposedActiveDevice;
    private BluetoothDevice mActiveDevice;
    private boolean mAudioRouteAllowed = true;
    // Indicates whether SCO audio needs to be forced to open regardless ANY OTHER restrictions
@@ -155,6 +157,8 @@ public class HeadsetService extends ProfileService {
    // Timeout when voice recognition is started by remote device
    @VisibleForTesting static int sStartVrTimeoutMs = 5000;
    private ArrayList<StateMachineTask> mPendingClccResponses = new ArrayList<>();
    private final AudioManagerAudioDeviceCallback mAudioManagerAudioDeviceCallback =
            new AudioManagerAudioDeviceCallback();
    private static HeadsetService sHeadsetService;

    @VisibleForTesting boolean mIsAptXSwbEnabled = false;
@@ -208,7 +212,14 @@ public class HeadsetService extends ProfileService {
        mNativeInterface.init(mMaxHeadsetConnections + 1, isInbandRingingEnabled());
        enableSwbCodec(
                HeadsetHalConstants.BTHF_SWB_CODEC_VENDOR_APTX, mIsAptXSwbEnabled, mActiveDevice);
        // Step 6: Setup broadcast receivers
        // Step 6: Register Audio Device callback
        if (Utils.isScoManagedByAudioEnabled()) {
            mSystemInterface
                    .getAudioManager()
                    .registerAudioDeviceCallback(mAudioManagerAudioDeviceCallback, mHandler);
        }

        // Step 7: Setup broadcast receivers
        IntentFilter filter = new IntentFilter();
        filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
        filter.addAction(Intent.ACTION_BATTERY_CHANGED);
@@ -229,11 +240,20 @@ public class HeadsetService extends ProfileService {
    @Override
    public void stop() {
        Log.i(TAG, "stop()");
        // Step 6: Tear down broadcast receivers
        // Step 7: Tear down broadcast receivers
        unregisterReceiver(mHeadsetReceiver);

        // Step 6: Unregister Audio Device Callback
        if (Utils.isScoManagedByAudioEnabled()) {
            mSystemInterface
                    .getAudioManager()
                    .unregisterAudioDeviceCallback(mAudioManagerAudioDeviceCallback);
        }

        synchronized (mStateMachines) {
            // Reset active device to null
            if (mActiveDevice != null) {
                mExposedActiveDevice = null;
                mActiveDevice = null;
                broadcastActiveDevice(null);
            }
@@ -1397,6 +1417,8 @@ public class HeadsetService extends ProfileService {
            }

            // Make sure the Audio Manager knows the previous active device is no longer active.
            mActiveDevice = null;
            mNativeInterface.setActiveDevice(null);
            if (Utils.isScoManagedByAudioEnabled()) {
                mSystemInterface
                        .getAudioManager()
@@ -1404,11 +1426,10 @@ public class HeadsetService extends ProfileService {
                                null,
                                mActiveDevice,
                                BluetoothProfileConnectionInfo.createHfpInfo());
            } else {
                broadcastActiveDevice(null);
            }

            mActiveDevice = null;
            mNativeInterface.setActiveDevice(null);
            broadcastActiveDevice(null);
            if (Flags.updateActiveDeviceInBandRingtone()) {
                updateInbandRinging(null, true);
            }
@@ -1480,8 +1501,9 @@ public class HeadsetService extends ProfileService {
                                    mActiveDevice,
                                    previousActiveDevice,
                                    BluetoothProfileConnectionInfo.createHfpInfo());
                }
                } else {
                    broadcastActiveDevice(mActiveDevice);
                }
                if (Flags.updateActiveDeviceInBandRingtone()) {
                    updateInbandRinging(device, true);
                }
@@ -1494,12 +1516,10 @@ public class HeadsetService extends ProfileService {
                                    mActiveDevice,
                                    previousActiveDevice,
                                    BluetoothProfileConnectionInfo.createHfpInfo());
                }
                broadcastActiveDevice(mActiveDevice);
                if (Utils.isScoManagedByAudioEnabled()) {
                    // Audio Framework will handle audio transition
                    return true;
                }
                broadcastActiveDevice(mActiveDevice);
                int connectStatus = connectAudio(mActiveDevice);
                if (connectStatus != BluetoothStatusCodes.SUCCESS) {
                    Log.e(
@@ -1525,8 +1545,9 @@ public class HeadsetService extends ProfileService {
                                    mActiveDevice,
                                    previousActiveDevice,
                                    BluetoothProfileConnectionInfo.createHfpInfo());
                }
                } else {
                    broadcastActiveDevice(mActiveDevice);
                }
                if (Flags.updateActiveDeviceInBandRingtone()) {
                    updateInbandRinging(device, true);
                }
@@ -2398,6 +2419,95 @@ public class HeadsetService extends ProfileService {
                Utils.getTempBroadcastOptions().toBundle());
    }

    /* Notifications of audio device connection/disconnection events. */
    private class AudioManagerAudioDeviceCallback extends AudioDeviceCallback {
        @Override
        public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) {
            if (mSystemInterface.getAudioManager() == null || mAdapterService == null) {
                Log.e(TAG, "Callback called when A2dpService is stopped");
                return;
            }

            synchronized (mStateMachines) {
                for (AudioDeviceInfo deviceInfo : addedDevices) {
                    if (deviceInfo.getType() != AudioDeviceInfo.TYPE_BLUETOOTH_SCO) {
                        continue;
                    }

                    String address = deviceInfo.getAddress();
                    if (address.equals("00:00:00:00:00:00")) {
                        continue;
                    }

                    byte[] addressBytes = Utils.getBytesFromAddress(address);
                    BluetoothDevice device = mAdapterService.getDeviceFromByte(addressBytes);

                    Log.d(
                            TAG,
                            " onAudioDevicesAdded: "
                                    + device
                                    + ", device type: "
                                    + deviceInfo.getType());

                    /* Don't expose already exposed active device */
                    if (device.equals(mExposedActiveDevice)) {
                        Log.d(TAG, " onAudioDevicesAdded: " + device + " is already exposed");
                        return;
                    }

                    if (!device.equals(mActiveDevice)) {
                        Log.e(
                                TAG,
                                "Added device does not match to the one activated here. ("
                                        + device
                                        + " != "
                                        + mActiveDevice
                                        + " / "
                                        + mActiveDevice
                                        + ")");
                        continue;
                    }

                    mExposedActiveDevice = device;
                    broadcastActiveDevice(device);
                    return;
                }
            }
        }

        @Override
        public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {
            if (mSystemInterface.getAudioManager() == null || mAdapterService == null) {
                Log.e(TAG, "Callback called when LeAudioService is stopped");
                return;
            }

            synchronized (mStateMachines) {
                for (AudioDeviceInfo deviceInfo : removedDevices) {
                    if (deviceInfo.getType() != AudioDeviceInfo.TYPE_BLUETOOTH_SCO) {
                        continue;
                    }

                    String address = deviceInfo.getAddress();
                    if (address.equals("00:00:00:00:00:00")) {
                        continue;
                    }

                    mExposedActiveDevice = null;

                    Log.d(
                            TAG,
                            " onAudioDevicesRemoved: "
                                    + address
                                    + ", device type: "
                                    + deviceInfo.getType()
                                    + ", mActiveDevice: "
                                    + mActiveDevice);
                }
            }
        }
    }

    /**
     * Check whether it is OK to accept a headset connection from a remote device
     *
+0 −1
Original line number Diff line number Diff line
@@ -83,7 +83,6 @@ class HeadsetSystemInterface {
     *
     * @return audio manager for setting audio parameters
     */
    @VisibleForTesting
    public AudioManager getAudioManager() {
        return mAudioManager;
    }