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

Commit 67ec4f13 authored by Pavlin Radoslavov's avatar Pavlin Radoslavov
Browse files

Allow outgoing A2DP connection when pairing via NFC

If Bluetooth is disabled, pairing via NFC will start the Bluetooth
Adapter service in Quiet Mode. In such mode only the incoming A2DP
connection requests should be rejected - the outgoing A2DP connection
requests should be allowed.

Bug: 79330878
Test: Manual: (1) Disable Bluetooth; (2) Pair with a Headset via NFC;
      (3) Play music. Updated existing unit tests.

Change-Id: I3dd892b963116c8f169f63bb117401a4a078ab9c
Merged-In: I3dd892b963116c8f169f63bb117401a4a078ab9c
(cherry picked from commit c713e54b82851072afdc5fb6bc6decc2f438d81b)
parent e26a3835
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -331,12 +331,15 @@ public class A2dpService extends ProfileService {
     * The check considers a number of factors during the evaluation.
     *
     * @param device the peer device to connect to
     * @param isOutgoingRequest if true, the check is for outgoing connection
     * request, otherwise is for incoming connection request
     * @return true if connection is allowed, otherwise false
     */
    @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
    public boolean okToConnect(BluetoothDevice device) {
    public boolean okToConnect(BluetoothDevice device, boolean isOutgoingRequest) {
        Log.i(TAG, "okToConnect: device " + device + " isOutgoingRequest: " + isOutgoingRequest);
        // Check if this is an incoming connection in Quiet mode.
        if (mAdapterService.isQuietModeEnabled()) {
        if (mAdapterService.isQuietModeEnabled() && !isOutgoingRequest) {
            Log.e(TAG, "okToConnect: cannot connect to " + device + " : quiet mode enabled");
            return false;
        }
+5 −5
Original line number Diff line number Diff line
@@ -185,7 +185,7 @@ final class A2dpStateMachine extends StateMachine {
                        Log.e(TAG, "Disconnected: error connecting to " + mDevice);
                        break;
                    }
                    if (mA2dpService.okToConnect(mDevice)) {
                    if (mA2dpService.okToConnect(mDevice, true)) {
                        transitionTo(mConnecting);
                    } else {
                        // Reject the request and stay in Disconnected state
@@ -226,7 +226,7 @@ final class A2dpStateMachine extends StateMachine {
                    Log.w(TAG, "Ignore A2DP DISCONNECTED event: " + mDevice);
                    break;
                case A2dpStackEvent.CONNECTION_STATE_CONNECTING:
                    if (mA2dpService.okToConnect(mDevice)) {
                    if (mA2dpService.okToConnect(mDevice, false)) {
                        Log.i(TAG, "Incoming A2DP Connecting request accepted: " + mDevice);
                        transitionTo(mConnecting);
                    } else {
@@ -237,7 +237,7 @@ final class A2dpStateMachine extends StateMachine {
                    break;
                case A2dpStackEvent.CONNECTION_STATE_CONNECTED:
                    Log.w(TAG, "A2DP Connected from Disconnected state: " + mDevice);
                    if (mA2dpService.okToConnect(mDevice)) {
                    if (mA2dpService.okToConnect(mDevice, false)) {
                        Log.i(TAG, "Incoming A2DP Connected request accepted: " + mDevice);
                        transitionTo(mConnected);
                    } else {
@@ -428,7 +428,7 @@ final class A2dpStateMachine extends StateMachine {
                    transitionTo(mDisconnected);
                    break;
                case A2dpStackEvent.CONNECTION_STATE_CONNECTED:
                    if (mA2dpService.okToConnect(mDevice)) {
                    if (mA2dpService.okToConnect(mDevice, false)) {
                        Log.w(TAG, "Disconnecting interrupted: device is connected: " + mDevice);
                        transitionTo(mConnected);
                    } else {
@@ -438,7 +438,7 @@ final class A2dpStateMachine extends StateMachine {
                    }
                    break;
                case A2dpStackEvent.CONNECTION_STATE_CONNECTING:
                    if (mA2dpService.okToConnect(mDevice)) {
                    if (mA2dpService.okToConnect(mDevice, false)) {
                        Log.i(TAG, "Disconnecting interrupted: try to reconnect: " + mDevice);
                        transitionTo(mConnecting);
                    } else {
+18 −7
Original line number Diff line number Diff line
@@ -90,6 +90,7 @@ public class A2dpServiceTest {

        TestUtils.setAdapterService(mAdapterService);
        doReturn(MAX_CONNECTED_AUDIO_DEVICES).when(mAdapterService).getMaxConnectedAudioDevices();
        doReturn(false).when(mAdapterService).isQuietModeEnabled();

        mAdapter = BluetoothAdapter.getDefaultAdapter();

@@ -851,7 +852,7 @@ public class A2dpServiceTest {
    }

    /**
     *  Helper function to test okToConnect() method
     * Helper function to test okToConnect() method.
     *
     * @param device test device
     * @param bondState bond state value, could be invalid
@@ -862,7 +863,17 @@ public class A2dpServiceTest {
            boolean expected) {
        doReturn(bondState).when(mAdapterService).getBondState(device);
        Assert.assertTrue(mA2dpService.setPriority(device, priority));
        Assert.assertEquals(expected, mA2dpService.okToConnect(device));
    }

        // Test when the AdapterService is in non-quiet mode: the result should not depend
        // on whether the connection request is outgoing or incoming.
        doReturn(false).when(mAdapterService).isQuietModeEnabled();
        Assert.assertEquals(expected, mA2dpService.okToConnect(device, true));  // Outgoing
        Assert.assertEquals(expected, mA2dpService.okToConnect(device, false)); // Incoming

        // Test when the AdapterService is in quiet mode: the result should always be
        // false when the connection request is incoming.
        doReturn(true).when(mAdapterService).isQuietModeEnabled();
        Assert.assertEquals(expected, mA2dpService.okToConnect(device, true));  // Outgoing
        Assert.assertEquals(false, mA2dpService.okToConnect(device, false)); // Incoming
    }
}
+2 −1
Original line number Diff line number Diff line
@@ -107,7 +107,8 @@ public class A2dpStateMachineTest {
     * @param allow if true, connection is allowed
     */
    private void allowConnection(boolean allow) {
        doReturn(allow).when(mA2dpService).okToConnect(any(BluetoothDevice.class));
        doReturn(allow).when(mA2dpService).okToConnect(any(BluetoothDevice.class),
                                                       anyBoolean());
    }

    /**