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

Commit 8703ebe1 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Fix background connection" into main

parents 29ca8128 481dfa26
Loading
Loading
Loading
Loading
+51 −25
Original line number Diff line number Diff line
@@ -31,7 +31,6 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;

import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.test_utils.EnableBluetoothRule;
import android.content.Context;
import android.platform.test.annotations.RequiresFlagsEnabled;
@@ -40,15 +39,17 @@ import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.util.Log;

import androidx.test.core.app.ApplicationProvider;
import androidx.test.platform.app.InstrumentationRegistry;

import com.android.bluetooth.flags.Flags;
import com.android.compatibility.common.util.AdoptShellPermissionsRule;

import com.google.protobuf.ByteString;
import com.google.testing.junit.testparameterinjector.TestParameter;
import com.google.testing.junit.testparameterinjector.TestParameterInjector;

import org.junit.After;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -73,6 +74,7 @@ import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.UUID;

@RunWith(TestParameterInjector.class)
@@ -98,15 +100,38 @@ public class GattClientTest {
    public final PandoraDevice mBumble = new PandoraDevice();

    @Rule(order = 2)
    public final AdoptShellPermissionsRule mPermissionRule = new AdoptShellPermissionsRule();

    @Rule(order = 3)
    public final EnableBluetoothRule mEnableBluetoothRule = new EnableBluetoothRule(false, true);

    private final Context mContext = ApplicationProvider.getApplicationContext();
    private final BluetoothManager mManager = mContext.getSystemService(BluetoothManager.class);
    private final BluetoothAdapter mAdapter = mManager.getAdapter();
    private final BluetoothLeScanner mLeScanner = mAdapter.getBluetoothLeScanner();

    private Host mHost;
    private BluetoothDevice mRemoteLeDevice;

    @Before
    public void setUp() throws Exception {
        InstrumentationRegistry.getInstrumentation()
                .getUiAutomation()
                .adoptShellPermissionIdentity();

        mHost = new Host(mContext);
        mRemoteLeDevice =
                mAdapter.getRemoteLeDevice(
                        Utils.BUMBLE_RANDOM_ADDRESS, BluetoothDevice.ADDRESS_TYPE_RANDOM);
        mRemoteLeDevice.removeBond();
    }

    @After
    public void tearUp() throws Exception {
        InstrumentationRegistry.getInstrumentation()
                .getUiAutomation()
                .dropShellPermissionIdentity();
        Set<BluetoothDevice> bondedDevices = mAdapter.getBondedDevices();
        if (bondedDevices.contains(mRemoteLeDevice)) {
            mRemoteLeDevice.removeBond();
        }
    }

    @Test
    public void directConnectGattAfterClose() throws Exception {
@@ -138,9 +163,12 @@ public class GattClientTest {
    }

    @Test
    public void fullGattClientLifecycle() throws Exception {
    public void fullGattClientLifecycle(@TestParameter boolean autoConnect) {
        if (autoConnect) {
            createLeBondAndWaitBonding(mRemoteLeDevice);
        }
        BluetoothGattCallback gattCallback = mock(BluetoothGattCallback.class);
        BluetoothGatt gatt = connectGattAndWaitConnection(gattCallback);
        BluetoothGatt gatt = connectGattAndWaitConnection(gattCallback, autoConnect);
        disconnectAndWaitDisconnection(gatt, gattCallback);
    }

@@ -148,13 +176,10 @@ public class GattClientTest {
    public void reconnectExistingClient() throws Exception {
        advertiseWithBumble();

        BluetoothDevice device =
                mAdapter.getRemoteLeDevice(
                        Utils.BUMBLE_RANDOM_ADDRESS, BluetoothDevice.ADDRESS_TYPE_RANDOM);
        BluetoothGattCallback gattCallback = mock(BluetoothGattCallback.class);
        InOrder inOrder = inOrder(gattCallback);

        BluetoothGatt gatt = device.connectGatt(mContext, false, gattCallback);
        BluetoothGatt gatt = mRemoteLeDevice.connectGatt(mContext, false, gattCallback);
        inOrder.verify(gattCallback, timeout(1000))
                .onConnectionStateChange(any(), anyInt(), eq(STATE_CONNECTED));

@@ -465,30 +490,27 @@ public class GattClientTest {
    }

    private BluetoothGatt connectGattAndWaitConnection(BluetoothGattCallback callback) {
        return connectGattAndWaitConnection(callback, /* autoConnect= */ false);
    }

    private BluetoothGatt connectGattAndWaitConnection(
            BluetoothGattCallback callback, boolean autoConnect) {
        final int status = GATT_SUCCESS;
        final int state = STATE_CONNECTED;

        advertiseWithBumble();

        BluetoothDevice device =
                mAdapter.getRemoteLeDevice(
                        Utils.BUMBLE_RANDOM_ADDRESS, BluetoothDevice.ADDRESS_TYPE_RANDOM);

        BluetoothGatt gatt = device.connectGatt(mContext, false, callback);
        BluetoothGatt gatt = mRemoteLeDevice.connectGatt(mContext, autoConnect, callback);
        verify(callback, timeout(1000)).onConnectionStateChange(eq(gatt), eq(status), eq(state));

        return gatt;
    }

    /** Tries to connect GATT, it could fail and return null. */
    private BluetoothGatt tryConnectGatt(BluetoothGattCallback callback) {
    private BluetoothGatt tryConnectGatt(BluetoothGattCallback callback, boolean autoConnect) {
        advertiseWithBumble();

        BluetoothDevice device =
                mAdapter.getRemoteLeDevice(
                        Utils.BUMBLE_RANDOM_ADDRESS, BluetoothDevice.ADDRESS_TYPE_RANDOM);

        BluetoothGatt gatt = device.connectGatt(mContext, false, callback);
        BluetoothGatt gatt = mRemoteLeDevice.connectGatt(mContext, autoConnect, callback);

        ArgumentCaptor<Integer> statusCaptor = ArgumentCaptor.forClass(Integer.class);
        ArgumentCaptor<Integer> stateCaptor = ArgumentCaptor.forClass(Integer.class);
@@ -596,7 +618,6 @@ public class GattClientTest {
    @Test
    @RequiresFlagsEnabled(Flags.FLAG_GATT_CLIENT_DYNAMIC_ALLOCATION)
    public void connectGatt_multipleClients() {
        advertiseWithBumble();
        registerGattService();

        List<BluetoothGatt> gatts = new ArrayList<>();
@@ -606,7 +627,7 @@ public class GattClientTest {
        try {
            for (int i = 0; i < repeatTimes; i++) {
                BluetoothGattCallback gattCallback = mock(BluetoothGattCallback.class);
                BluetoothGatt gatt = tryConnectGatt(gattCallback);
                BluetoothGatt gatt = tryConnectGatt(gattCallback, false);
                // If it fails, close an existing gatt instance and try again.
                if (gatt == null) {
                    failed = true;
@@ -664,4 +685,9 @@ public class GattClientTest {
            gatt.close();
        }
    }

    private void createLeBondAndWaitBonding(BluetoothDevice device) {
        advertiseWithBumble();
        mHost.createBondAndVerify(device);
    }
}
+15 −6
Original line number Diff line number Diff line
@@ -691,9 +691,12 @@ bool bta_gattc_mark_bg_conn(tGATT_IF client_if, const RawAddress& remote_bda_ptr
        p_bg_tck->in_use = true;
        p_bg_tck->remote_bda = remote_bda_ptr;

        if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
          p_bg_tck->cif_set = {client_if};
        } else {
          p_cif_mask = &p_bg_tck->cif_mask;

          *p_cif_mask = ((tBTA_GATTC_CIF_MASK)1 << (client_if - 1));
        }
        return true;
      }
    }
@@ -719,12 +722,18 @@ bool bta_gattc_check_bg_conn(tGATT_IF client_if, const RawAddress& remote_bda, u
  for (i = 0; i < ble_acceptlist_size() && !is_bg_conn; i++, p_bg_tck++) {
    if (p_bg_tck->in_use &&
        (p_bg_tck->remote_bda == remote_bda || p_bg_tck->remote_bda.IsEmpty())) {
      if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
        if (p_bg_tck->cif_set.contains(client_if) && role == HCI_ROLE_CENTRAL) {
          is_bg_conn = true;
        }
      } else {
        if (((p_bg_tck->cif_mask & ((tBTA_GATTC_CIF_MASK)1 << (client_if - 1))) != 0) &&
            role == HCI_ROLE_CENTRAL) {
          is_bg_conn = true;
        }
      }
    }
  }
  return is_bg_conn;
}
/*******************************************************************************