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

Commit 19177e97 authored by Sal Savage's avatar Sal Savage Committed by Automerger Merge Worker
Browse files

Merge "Use getMaxConnectedAudioDevices when initializing the native stack" am:...

Merge "Use getMaxConnectedAudioDevices when initializing the native stack" am: 8496b3a4 am: 41399630 am: 3c0a014a

Original change: https://android-review.googlesource.com/c/platform/packages/apps/Bluetooth/+/1584292

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I3b539e0f3f385e942a84353c0237362d7663fd5a
parents 6c994a6f 3c0a014a
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -109,7 +109,8 @@ static void classInitNative(JNIEnv* env, jclass clazz) {
  ALOGI("%s: succeeds", __func__);
}

static void initNative(JNIEnv* env, jobject object) {
static void initNative(JNIEnv* env, jobject object,
                       jint maxConnectedAudioDevices) {
  const bt_interface_t* btInf = getBluetoothInterface();
  if (btInf == NULL) {
    ALOGE("Bluetooth module is not loaded");
@@ -136,7 +137,8 @@ static void initNative(JNIEnv* env, jobject object) {
    return;
  }

  bt_status_t status = sBluetoothA2dpInterface->init(&sBluetoothA2dpCallbacks);
  bt_status_t status = sBluetoothA2dpInterface->init(&sBluetoothA2dpCallbacks,
                                                     maxConnectedAudioDevices);
  if (status != BT_STATUS_SUCCESS) {
    ALOGE("Failed to initialize Bluetooth A2DP Sink, status: %d", status);
    sBluetoothA2dpInterface = NULL;
@@ -243,7 +245,7 @@ static jboolean setActiveDeviceNative(JNIEnv* env, jobject object,

static JNINativeMethod sMethods[] = {
    {"classInitNative", "()V", (void*)classInitNative},
    {"initNative", "()V", (void*)initNative},
    {"initNative", "(I)V", (void*)initNative},
    {"cleanupNative", "()V", (void*)cleanupNative},
    {"connectA2dpNative", "([B)Z", (void*)connectA2dpNative},
    {"disconnectA2dpNative", "([B)Z", (void*)disconnectA2dpNative},
+43 −8
Original line number Diff line number Diff line
@@ -34,7 +34,6 @@ import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
@@ -44,15 +43,18 @@ import java.util.concurrent.ConcurrentHashMap;
public class A2dpSinkService extends ProfileService {
    private static final String TAG = "A2dpSinkService";
    private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
    static final int MAXIMUM_CONNECTED_DEVICES = 1;
    private int mMaxConnectedAudioDevices;

    private final BluetoothAdapter mAdapter;
    private AdapterService mAdapterService;
    private DatabaseManager mDatabaseManager;
    protected Map<BluetoothDevice, A2dpSinkStateMachine> mDeviceStateMap =
            new ConcurrentHashMap<>(1);

    private final Object mStreamHandlerLock = new Object();

    private final Object mActiveDeviceLock = new Object();
    private BluetoothDevice mActiveDevice = null;

    private A2dpSinkStreamHandler mA2dpSinkStreamHandler;
    private static A2dpSinkService sService;

@@ -62,13 +64,16 @@ public class A2dpSinkService extends ProfileService {

    @Override
    protected boolean start() {
        mAdapterService = Objects.requireNonNull(AdapterService.getAdapterService(),
                "AdapterService cannot be null when A2dpSinkService starts");
        mDatabaseManager = Objects.requireNonNull(AdapterService.getAdapterService().getDatabase(),
                "DatabaseManager cannot be null when A2dpSinkService starts");

        synchronized (mStreamHandlerLock) {
            mA2dpSinkStreamHandler = new A2dpSinkStreamHandler(this, this);
        }
        initNative();
        mMaxConnectedAudioDevices = mAdapterService.getMaxConnectedAudioDevices();
        initNative(mMaxConnectedAudioDevices);
        setA2dpSinkService(this);
        return true;
    }
@@ -104,8 +109,36 @@ public class A2dpSinkService extends ProfileService {
    }


    public A2dpSinkService() {
        mAdapter = BluetoothAdapter.getDefaultAdapter();
    public A2dpSinkService() {}

    /**
     * Set the device that should be allowed to actively stream
     */
    public boolean setActiveDevice(BluetoothDevice device) {
        // Translate to byte address for JNI. Use an all 0 MAC for no active device
        byte[] address = null;
        if (device != null) {
            address = Utils.getByteAddress(device);
        } else {
            address = Utils.getBytesFromAddress("00:00:00:00:00:00");
        }

        synchronized (mActiveDeviceLock) {
            if (setActiveDeviceNative(address)) {
                mActiveDevice = device;
                return true;
            }
            return false;
        }
    }

    /**
     * Get the device that is allowed to be actively streaming
     */
    public BluetoothDevice getActiveDevice() {
        synchronized (mActiveDeviceLock) {
            return mActiveDevice;
        }
    }

    /**
@@ -343,7 +376,7 @@ public class A2dpSinkService extends ProfileService {
    List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
        if (DBG) Log.d(TAG, "getDevicesMatchingConnectionStates" + Arrays.toString(states));
        List<BluetoothDevice> deviceList = new ArrayList<>();
        Set<BluetoothDevice> bondedDevices = mAdapter.getBondedDevices();
        BluetoothDevice[] bondedDevices = mAdapterService.getBondedDevices();
        int connectionState;
        for (BluetoothDevice device : bondedDevices) {
            connectionState = getConnectionState(device);
@@ -425,6 +458,8 @@ public class A2dpSinkService extends ProfileService {
    @Override
    public void dump(StringBuilder sb) {
        super.dump(sb);
        ProfileService.println(sb, "Active Device = " + getActiveDevice());
        ProfileService.println(sb, "Max Connected Devices = " + mMaxConnectedAudioDevices);
        ProfileService.println(sb, "Devices Tracked = " + mDeviceStateMap.size());
        for (A2dpSinkStateMachine stateMachine : mDeviceStateMap.values()) {
            ProfileService.println(sb,
@@ -446,7 +481,7 @@ public class A2dpSinkService extends ProfileService {

    private static native void classInitNative();

    private native void initNative();
    private native void initNative(int maxConnectedAudioDevices);

    private native void cleanupNative();

+6 −6
Original line number Diff line number Diff line
@@ -249,17 +249,16 @@ class AvrcpControllerStateMachine extends StateMachine {
     */
    boolean setActive(boolean becomeActive) {
        logD("setActive(" + becomeActive + ")");
        if (becomeActive) {
            if (isActive()) {
                return true;
            }

        A2dpSinkService a2dpSinkService = A2dpSinkService.getA2dpSinkService();
        if (a2dpSinkService == null) {
            return false;
        }
        if (becomeActive) {
            if (isActive()) {
                return true;
            }

            if (a2dpSinkService.setActiveDeviceNative(mDeviceAddress)) {
            if (a2dpSinkService.setActiveDevice(mDevice)) {
                sActiveDevice = mDevice;
                BluetoothMediaBrowserService.addressedPlayerChanged(mSessionCallbacks);
                BluetoothMediaBrowserService.notifyChanged(mAddressedPlayer.getPlaybackState());
@@ -268,6 +267,7 @@ class AvrcpControllerStateMachine extends StateMachine {
            return mDevice == sActiveDevice;
        } else if (isActive()) {
            sActiveDevice = null;
            a2dpSinkService.setActiveDevice(null);
            BluetoothMediaBrowserService.trackChanged(null);
            BluetoothMediaBrowserService.addressedPlayerChanged(null);
        }
+34 −0
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@ public class A2dpSinkServiceTest {
        MockitoAnnotations.initMocks(this);
        TestUtils.setAdapterService(mAdapterService);
        doReturn(mDatabaseManager).when(mAdapterService).getDatabase();
        setMaxConnectedAudioDevices(1);
        TestUtils.startService(mServiceRule, A2dpSinkService.class);
        mService = A2dpSinkService.getA2dpSinkService();
        Assert.assertNotNull(mService);
@@ -85,6 +86,13 @@ public class A2dpSinkServiceTest {
        return mAdapter.getRemoteDevice(address);
    }

    /**
     * Set the upper connected device limit
     */
    private void setMaxConnectedAudioDevices(int maxConnectedAudioDevices) {
        when(mAdapterService.getMaxConnectedAudioDevices()).thenReturn(maxConnectedAudioDevices);
    }

    /**
     * Mock the priority of a bluetooth device
     *
@@ -120,4 +128,30 @@ public class A2dpSinkServiceTest {
        mockDevicePriority(device, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN);
        Assert.assertFalse(mService.connect(device));
    }

    /**
     * Test that we can connect multiple devices
     */
    @Test
    public void testConnectMultipleDevices() {
        setMaxConnectedAudioDevices(5);

        BluetoothDevice device1 = makeBluetoothDevice("11:11:11:11:11:11");
        BluetoothDevice device2 = makeBluetoothDevice("22:22:22:22:22:22");
        BluetoothDevice device3 = makeBluetoothDevice("33:33:33:33:33:33");
        BluetoothDevice device4 = makeBluetoothDevice("44:44:44:44:44:44");
        BluetoothDevice device5 = makeBluetoothDevice("55:55:55:55:55:55");

        mockDevicePriority(device1, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
        mockDevicePriority(device2, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
        mockDevicePriority(device3, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
        mockDevicePriority(device4, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
        mockDevicePriority(device5, BluetoothProfile.CONNECTION_POLICY_ALLOWED);

        Assert.assertTrue(mService.connect(device1));
        Assert.assertTrue(mService.connect(device2));
        Assert.assertTrue(mService.connect(device3));
        Assert.assertTrue(mService.connect(device4));
        Assert.assertTrue(mService.connect(device5));
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -113,7 +113,7 @@ public class AvrcpControllerStateMachineTest {
        TestUtils.setAdapterService(mA2dpAdapterService);
        doReturn(mDatabaseManager).when(mA2dpAdapterService).getDatabase();
        TestUtils.startService(mA2dpServiceRule, A2dpSinkService.class);
        when(mA2dpSinkService.setActiveDeviceNative(any())).thenReturn(true);
        when(mA2dpSinkService.setActiveDevice(any())).thenReturn(true);

        when(mMockResources.getBoolean(R.bool.a2dp_sink_automatically_request_audio_focus))
                .thenReturn(true);