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

Commit c077921e authored by Eric Laurent's avatar Eric Laurent Committed by Automerger Merge Worker
Browse files

Merge "AudioService: synchronize BT_SCO on and A2DP or LE suspended states -...

Merge "AudioService: synchronize BT_SCO on and A2DP or LE suspended states - take 2" into udc-dev am: f2afed1d am: a3bc28b8

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/23209617



Change-Id: If716355db65270185d737aba24eb0970edca9e44
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents d40b45b1 a3bc28b8
Loading
Loading
Loading
Loading
+12 −2
Original line number Diff line number Diff line
@@ -3730,7 +3730,12 @@ public class AudioManager {
    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
    @RequiresPermission(Manifest.permission.BLUETOOTH_STACK)
    public void setA2dpSuspended(boolean enable) {
        AudioSystem.setParameters("A2dpSuspended=" + enable);
        final IAudioService service = getService();
        try {
            service.setA2dpSuspended(enable);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
@@ -3743,7 +3748,12 @@ public class AudioManager {
    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
    @RequiresPermission(Manifest.permission.BLUETOOTH_STACK)
    public void setLeAudioSuspended(boolean enable) {
        AudioSystem.setParameters("LeAudioSuspended=" + enable);
        final IAudioService service = getService();
        try {
            service.setLeAudioSuspended(enable);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
+6 −0
Original line number Diff line number Diff line
@@ -231,6 +231,12 @@ interface IAudioService {

    void setBluetoothScoOn(boolean on);

    @EnforcePermission("BLUETOOTH_STACK")
    void setA2dpSuspended(boolean on);

    @EnforcePermission("BLUETOOTH_STACK")
    void setLeAudioSuspended(boolean enable);

    boolean isBluetoothScoOn();

    void setBluetoothA2dpOn(boolean on);
+163 −11
Original line number Diff line number Diff line
@@ -209,6 +209,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
    private void init() {
        setupMessaging(mContext);

        initAudioHalBluetoothState();
        initRoutingStrategyIds();
        mPreferredCommunicationDevice = null;
        updateActiveCommunicationDevice();
@@ -864,21 +865,174 @@ import java.util.concurrent.atomic.AtomicBoolean;
        }
    }

    /**
     * Current Bluetooth SCO audio active state indicated by BtHelper via setBluetoothScoOn().
     */
    // Lock protecting state variable related to Bluetooth audio state
    private final Object mBluetoothAudioStateLock = new Object();

    // Current Bluetooth SCO audio active state indicated by BtHelper via setBluetoothScoOn().
    @GuardedBy("mBluetoothAudioStateLock")
    private boolean mBluetoothScoOn;
    // value of BT_SCO parameter currently applied to audio HAL.
    @GuardedBy("mBluetoothAudioStateLock")
    private boolean mBluetoothScoOnApplied;

    // A2DP suspend state requested by AudioManager.setA2dpSuspended() API.
    @GuardedBy("mBluetoothAudioStateLock")
    private boolean mBluetoothA2dpSuspendedExt;
    // A2DP suspend state requested by AudioDeviceInventory.
    @GuardedBy("mBluetoothAudioStateLock")
    private boolean mBluetoothA2dpSuspendedInt;
    // value of BT_A2dpSuspendedSCO parameter currently applied to audio HAL.

    @GuardedBy("mBluetoothAudioStateLock")
    private boolean mBluetoothA2dpSuspendedApplied;

    // LE Audio suspend state requested by AudioManager.setLeAudioSuspended() API.
    @GuardedBy("mBluetoothAudioStateLock")
    private boolean mBluetoothLeSuspendedExt;
    // LE Audio suspend state requested by AudioDeviceInventory.
    @GuardedBy("mBluetoothAudioStateLock")
    private boolean mBluetoothLeSuspendedInt;
    // value of LeAudioSuspended parameter currently applied to audio HAL.
    @GuardedBy("mBluetoothAudioStateLock")
    private boolean mBluetoothLeSuspendedApplied;

    private void initAudioHalBluetoothState() {
        synchronized (mBluetoothAudioStateLock) {
            mBluetoothScoOnApplied = false;
            AudioSystem.setParameters("BT_SCO=off");
            mBluetoothA2dpSuspendedApplied = false;
            AudioSystem.setParameters("A2dpSuspended=false");
            mBluetoothLeSuspendedApplied = false;
            AudioSystem.setParameters("LeAudioSuspended=false");
        }
    }

    @GuardedBy("mBluetoothAudioStateLock")
    private void updateAudioHalBluetoothState() {
        if (mBluetoothScoOn != mBluetoothScoOnApplied) {
            if (AudioService.DEBUG_COMM_RTE) {
                Log.v(TAG, "updateAudioHalBluetoothState() mBluetoothScoOn: "
                        + mBluetoothScoOn + ", mBluetoothScoOnApplied: " + mBluetoothScoOnApplied);
            }
            if (mBluetoothScoOn) {
                if (!mBluetoothA2dpSuspendedApplied) {
                    AudioSystem.setParameters("A2dpSuspended=true");
                    mBluetoothA2dpSuspendedApplied = true;
                }
                if (!mBluetoothLeSuspendedApplied) {
                    AudioSystem.setParameters("LeAudioSuspended=true");
                    mBluetoothLeSuspendedApplied = true;
                }
                AudioSystem.setParameters("BT_SCO=on");
            } else {
                AudioSystem.setParameters("BT_SCO=off");
            }
            mBluetoothScoOnApplied = mBluetoothScoOn;
        }
        if (!mBluetoothScoOnApplied) {
            if ((mBluetoothA2dpSuspendedExt || mBluetoothA2dpSuspendedInt)
                    != mBluetoothA2dpSuspendedApplied) {
                if (AudioService.DEBUG_COMM_RTE) {
                    Log.v(TAG, "updateAudioHalBluetoothState() mBluetoothA2dpSuspendedExt: "
                            + mBluetoothA2dpSuspendedExt
                            + ", mBluetoothA2dpSuspendedInt: " + mBluetoothA2dpSuspendedInt
                            + ", mBluetoothA2dpSuspendedApplied: "
                            + mBluetoothA2dpSuspendedApplied);
                }
                mBluetoothA2dpSuspendedApplied =
                        mBluetoothA2dpSuspendedExt || mBluetoothA2dpSuspendedInt;
                if (mBluetoothA2dpSuspendedApplied) {
                    AudioSystem.setParameters("A2dpSuspended=true");
                } else {
                    AudioSystem.setParameters("A2dpSuspended=false");
                }
            }
            if ((mBluetoothLeSuspendedExt || mBluetoothLeSuspendedInt)
                    != mBluetoothLeSuspendedApplied) {
                if (AudioService.DEBUG_COMM_RTE) {
                    Log.v(TAG, "updateAudioHalBluetoothState() mBluetoothLeSuspendedExt: "
                            + mBluetoothLeSuspendedExt
                            + ", mBluetoothLeSuspendedInt: " + mBluetoothLeSuspendedInt
                            + ", mBluetoothLeSuspendedApplied: " + mBluetoothLeSuspendedApplied);
                }
                mBluetoothLeSuspendedApplied =
                        mBluetoothLeSuspendedExt || mBluetoothLeSuspendedInt;
                if (mBluetoothLeSuspendedApplied) {
                    AudioSystem.setParameters("LeAudioSuspended=true");
                } else {
                    AudioSystem.setParameters("LeAudioSuspended=false");
                }
            }
        }
    }

    /*package*/ void setBluetoothScoOn(boolean on, String eventSource) {
        if (AudioService.DEBUG_COMM_RTE) {
            Log.v(TAG, "setBluetoothScoOn: " + on + " " + eventSource);
        }
        synchronized (mDeviceStateLock) {
        synchronized (mBluetoothAudioStateLock) {
            mBluetoothScoOn = on;
            updateAudioHalBluetoothState();
            postUpdateCommunicationRouteClient(eventSource);
        }
    }

    /*package*/ void setA2dpSuspended(boolean enable, boolean internal, String eventSource) {
        synchronized (mBluetoothAudioStateLock) {
            if (AudioService.DEBUG_COMM_RTE) {
                Log.v(TAG, "setA2dpSuspended source: " + eventSource + ", enable: "
                        + enable + ", internal: " + internal
                        + ", mBluetoothA2dpSuspendedInt: " + mBluetoothA2dpSuspendedInt
                        + ", mBluetoothA2dpSuspendedExt: " + mBluetoothA2dpSuspendedExt);
            }
            if (internal) {
                mBluetoothA2dpSuspendedInt = enable;
            } else {
                mBluetoothA2dpSuspendedExt = enable;
            }
            updateAudioHalBluetoothState();
        }
    }

    /*package*/ void clearA2dpSuspended() {
        if (AudioService.DEBUG_COMM_RTE) {
            Log.v(TAG, "clearA2dpSuspended");
        }
        synchronized (mBluetoothAudioStateLock) {
            mBluetoothA2dpSuspendedInt = false;
            mBluetoothA2dpSuspendedExt = false;
            updateAudioHalBluetoothState();
        }
    }

    /*package*/ void setLeAudioSuspended(boolean enable, boolean internal, String eventSource) {
        synchronized (mBluetoothAudioStateLock) {
            if (AudioService.DEBUG_COMM_RTE) {
                Log.v(TAG, "setLeAudioSuspended source: " + eventSource + ", enable: "
                        + enable + ", internal: " + internal
                        + ", mBluetoothLeSuspendedInt: " + mBluetoothA2dpSuspendedInt
                        + ", mBluetoothLeSuspendedExt: " + mBluetoothA2dpSuspendedExt);
            }
            if (internal) {
                mBluetoothLeSuspendedInt = enable;
            } else {
                mBluetoothLeSuspendedExt = enable;
            }
            updateAudioHalBluetoothState();
        }
    }

    /*package*/ void clearLeAudioSuspended() {
        if (AudioService.DEBUG_COMM_RTE) {
            Log.v(TAG, "clearLeAudioSuspended");
        }
        synchronized (mBluetoothAudioStateLock) {
            mBluetoothLeSuspendedInt = false;
            mBluetoothLeSuspendedExt = false;
            updateAudioHalBluetoothState();
        }
    }

    /*package*/ AudioRoutesInfo startWatchingRoutes(IAudioRoutesObserver observer) {
        synchronized (mDeviceStateLock) {
            return mDeviceInventory.startWatchingRoutes(observer);
@@ -1985,7 +2139,11 @@ import java.util.concurrent.atomic.AtomicBoolean;
     */
    @GuardedBy("mDeviceStateLock")
    @Nullable private AudioDeviceAttributes preferredCommunicationDevice() {
        boolean btSCoOn = mBluetoothScoOn && mBtHelper.isBluetoothScoOn();
        boolean btSCoOn = mBtHelper.isBluetoothScoOn();
        synchronized (mBluetoothAudioStateLock) {
            btSCoOn = btSCoOn && mBluetoothScoOn;
        }

        if (btSCoOn) {
            // Use the SCO device known to BtHelper so that it matches exactly
            // what has been communicated to audio policy manager. The device
@@ -2020,12 +2178,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
                "updateCommunicationRoute, preferredCommunicationDevice: "
                + preferredCommunicationDevice + " eventSource: " + eventSource)));

        if (preferredCommunicationDevice == null
                || preferredCommunicationDevice.getType() != AudioDeviceInfo.TYPE_BLUETOOTH_SCO) {
            AudioSystem.setParameters("BT_SCO=off");
        } else {
            AudioSystem.setParameters("BT_SCO=on");
        }
        if (preferredCommunicationDevice == null) {
            AudioDeviceAttributes defaultDevice = getDefaultCommunicationDevice();
            if (defaultDevice != null) {
+6 −4
Original line number Diff line number Diff line
@@ -1479,7 +1479,7 @@ public class AudioDeviceInventory {
        }

        // Reset A2DP suspend state each time a new sink is connected
        mAudioSystem.setParameters("A2dpSuspended=false");
        mDeviceBroker.clearA2dpSuspended();

        // The convention for head tracking sensors associated with A2DP devices is to
        // use a UUID derived from the MAC address as follows:
@@ -1752,7 +1752,8 @@ public class AudioDeviceInventory {
    private void makeA2dpDeviceUnavailableLater(String address, int delayMs) {
        // prevent any activity on the A2DP audio output to avoid unwanted
        // reconnection of the sink.
        mAudioSystem.setParameters("A2dpSuspended=true");
        mDeviceBroker.setA2dpSuspended(
                true /*enable*/, true /*internal*/, "makeA2dpDeviceUnavailableLater");
        // retrieve DeviceInfo before removing device
        final String deviceKey =
                DeviceInfo.makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address);
@@ -1899,7 +1900,7 @@ public class AudioDeviceInventory {
                        "LE Audio device addr=" + address + " now available").printLog(TAG));
            }
            // Reset LEA suspend state each time a new sink is connected
            mAudioSystem.setParameters("LeAudioSuspended=false");
            mDeviceBroker.clearLeAudioSuspended();

            UUID sensorUuid = UuidUtils.uuidFromAudioDeviceAttributes(ada);
            mConnectedDevices.put(DeviceInfo.makeDeviceListKey(device, address),
@@ -1954,7 +1955,8 @@ public class AudioDeviceInventory {
    private void makeLeAudioDeviceUnavailableLater(String address, int device, int delayMs) {
        // prevent any activity on the LEA output to avoid unwanted
        // reconnection of the sink.
        mAudioSystem.setParameters("LeAudioSuspended=true");
        mDeviceBroker.setLeAudioSuspended(
                true /*enable*/, true /*internal*/, "makeLeAudioDeviceUnavailableLater");
        // the device will be made unavailable later, so consider it disconnected right away
        mConnectedDevices.remove(DeviceInfo.makeDeviceListKey(device, address));
        // send the delayed message to make the device unavailable later
+20 −0
Original line number Diff line number Diff line
@@ -6424,6 +6424,26 @@ public class AudioService extends IAudioService.Stub
        mDeviceBroker.setBluetoothScoOn(on, eventSource);
    }
    /** @see AudioManager#setA2dpSuspended(boolean) */
    @android.annotation.EnforcePermission(android.Manifest.permission.BLUETOOTH_STACK)
    public void setA2dpSuspended(boolean enable) {
        super.setA2dpSuspended_enforcePermission();
        final String eventSource = new StringBuilder("setA2dpSuspended(").append(enable)
                .append(") from u/pid:").append(Binder.getCallingUid()).append("/")
                .append(Binder.getCallingPid()).toString();
        mDeviceBroker.setA2dpSuspended(enable, false /*internal*/, eventSource);
    }
    /** @see AudioManager#setA2dpSuspended(boolean) */
    @android.annotation.EnforcePermission(android.Manifest.permission.BLUETOOTH_STACK)
    public void setLeAudioSuspended(boolean enable) {
        super.setLeAudioSuspended_enforcePermission();
        final String eventSource = new StringBuilder("setLeAudioSuspended(").append(enable)
                .append(") from u/pid:").append(Binder.getCallingUid()).append("/")
                .append(Binder.getCallingPid()).toString();
        mDeviceBroker.setLeAudioSuspended(enable, false /*internal*/, eventSource);
    }
    /** @see AudioManager#isBluetoothScoOn()
     * Note that it doesn't report internal state, but state seen by apps (which may have
     * called setBluetoothScoOn() */
Loading