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

Commit 55ad466f authored by Kyunglyul Hyun's avatar Kyunglyul Hyun Committed by Łukasz Rymanowski
Browse files

Tbs: Sets an active LE audio device when accepting calls

When accepting call from LE headset, call audio
should be routed to LE device even there is other active device on the
Android device.

This also fix scenario when peer device orginates the phonecall.

Bug: 232902624
Bug: 233006618

Tag: #feature
Test: atest BluetoothInstrumentationTests
Merged-In: I006d5762ba90fddd21fda261d6f3b99f84a29db4
Change-Id: I006d5762ba90fddd21fda261d6f3b99f84a29db4
(cherry picked from commit a5c60051)
parent a47ca87f
Loading
Loading
Loading
Loading
+20 −1
Original line number Original line Diff line number Diff line
@@ -35,6 +35,7 @@ import android.util.Log;
import com.android.bluetooth.btservice.ServiceFactory;
import com.android.bluetooth.btservice.ServiceFactory;
import com.android.bluetooth.le_audio.ContentControlIdKeeper;
import com.android.bluetooth.le_audio.ContentControlIdKeeper;
import com.android.bluetooth.le_audio.LeAudioService;
import com.android.bluetooth.le_audio.LeAudioService;
import com.android.internal.annotations.VisibleForTesting;


import java.util.ArrayList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Arrays;
@@ -735,7 +736,7 @@ public class TbsGeneric {
            mLastIndexAssigned = requestId;
            mLastIndexAssigned = requestId;
        }
        }



        setActiveLeDevice(device);
        return TbsGatt.CALL_CONTROL_POINT_RESULT_SUCCESS;
        return TbsGatt.CALL_CONTROL_POINT_RESULT_SUCCESS;
    }
    }


@@ -794,6 +795,7 @@ public class TbsGeneric {
                        Request request = new Request(device, callId, opcode, callIndex);
                        Request request = new Request(device, callId, opcode, callIndex);
                        try {
                        try {
                            if (opcode == TbsGatt.CALL_CONTROL_POINT_OPCODE_ACCEPT) {
                            if (opcode == TbsGatt.CALL_CONTROL_POINT_OPCODE_ACCEPT) {
                                setActiveLeDevice(device);
                                bearer.callback.onAcceptCall(requestId, new ParcelUuid(callId));
                                bearer.callback.onAcceptCall(requestId, new ParcelUuid(callId));
                            } else if (opcode == TbsGatt.CALL_CONTROL_POINT_OPCODE_TERMINATE) {
                            } else if (opcode == TbsGatt.CALL_CONTROL_POINT_OPCODE_TERMINATE) {
                                bearer.callback.onTerminateCall(requestId, new ParcelUuid(callId));
                                bearer.callback.onTerminateCall(requestId, new ParcelUuid(callId));
@@ -1023,6 +1025,11 @@ public class TbsGeneric {
        return true;
        return true;
    }
    }


    @VisibleForTesting
    void setLeAudioServiceForTesting(LeAudioService leAudioService) {
        mLeAudioService = leAudioService;
    }

    private synchronized void notifyCclc() {
    private synchronized void notifyCclc() {
        if (DBG) {
        if (DBG) {
            Log.d(TAG, "notifyCclc");
            Log.d(TAG, "notifyCclc");
@@ -1056,6 +1063,18 @@ public class TbsGeneric {
        mTbsGatt.setBearerUriSchemesSupportedList(mUriSchemes);
        mTbsGatt.setBearerUriSchemesSupportedList(mUriSchemes);
    }
    }


    private void setActiveLeDevice(BluetoothDevice device) {
        if (device == null) {
            Log.w(TAG, "setActiveLeDevice: ignore null device");
            return;
        }
        if (!isLeAudioServiceAvailable()) {
            Log.w(TAG, "mLeAudioService not available");
            return;
        }
        mLeAudioService.setActiveDevice(device);
    }

    private static boolean isCallStateTransitionValid(int callState, int requestedOpcode) {
    private static boolean isCallStateTransitionValid(int callState, int requestedOpcode) {
        switch (requestedOpcode) {
        switch (requestedOpcode) {
            case TbsGatt.CALL_CONTROL_POINT_OPCODE_ACCEPT:
            case TbsGatt.CALL_CONTROL_POINT_OPCODE_ACCEPT:
+12 −0
Original line number Original line Diff line number Diff line
@@ -35,6 +35,7 @@ import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentat


import com.android.bluetooth.TestUtils;
import com.android.bluetooth.TestUtils;
import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.le_audio.LeAudioService;


import org.junit.After;
import org.junit.After;
import org.junit.Before;
import org.junit.Before;
@@ -282,6 +283,9 @@ public class TbsGenericTest {
        Integer ccid = prepareTestBearer();
        Integer ccid = prepareTestBearer();
        reset(mTbsGatt);
        reset(mTbsGatt);


        LeAudioService leAudioService = mock(LeAudioService.class);
        mTbsGeneric.setLeAudioServiceForTesting(leAudioService);

        // Prepare the incoming call
        // Prepare the incoming call
        UUID callUuid = UUID.randomUUID();
        UUID callUuid = UUID.randomUUID();
        List<BluetoothLeCall> tbsCalls = new ArrayList<>();
        List<BluetoothLeCall> tbsCalls = new ArrayList<>();
@@ -310,6 +314,8 @@ public class TbsGenericTest {
            throw e.rethrowFromSystemServer();
            throw e.rethrowFromSystemServer();
        }
        }
        assertThat(callUuidCaptor.getValue().getUuid()).isEqualTo(callUuid);
        assertThat(callUuidCaptor.getValue().getUuid()).isEqualTo(callUuid);
        // Active device should be changed
        verify(leAudioService).setActiveDevice(mCurrentDevice);


        // Respond with requestComplete...
        // Respond with requestComplete...
        mTbsGeneric.requestResult(ccid, requestIdCaptor.getValue(), BluetoothLeCallControl.RESULT_SUCCESS);
        mTbsGeneric.requestResult(ccid, requestIdCaptor.getValue(), BluetoothLeCallControl.RESULT_SUCCESS);
@@ -462,6 +468,9 @@ public class TbsGenericTest {
        Integer ccid = prepareTestBearer();
        Integer ccid = prepareTestBearer();
        reset(mTbsGatt);
        reset(mTbsGatt);


        LeAudioService leAudioService = mock(LeAudioService.class);
        mTbsGeneric.setLeAudioServiceForTesting(leAudioService);

        // Act as if peer originates a call via Gtbs
        // Act as if peer originates a call via Gtbs
        String uri = "xmpp:123456789";
        String uri = "xmpp:123456789";
        mTbsGattCallback.getValue().onCallControlPointRequest(mCurrentDevice,
        mTbsGattCallback.getValue().onCallControlPointRequest(mCurrentDevice,
@@ -476,6 +485,9 @@ public class TbsGenericTest {
            throw e.rethrowFromSystemServer();
            throw e.rethrowFromSystemServer();
        }
        }


        // Active device should be changed
        verify(leAudioService).setActiveDevice(mCurrentDevice);

        // Respond with requestComplete...
        // Respond with requestComplete...
        mTbsGeneric.requestResult(ccid, requestIdCaptor.getValue(), BluetoothLeCallControl.RESULT_SUCCESS);
        mTbsGeneric.requestResult(ccid, requestIdCaptor.getValue(), BluetoothLeCallControl.RESULT_SUCCESS);
        mTbsGeneric.callAdded(ccid,
        mTbsGeneric.callAdded(ccid,