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

Commit 7090e284 authored by Omair Kamil's avatar Omair Kamil Committed by Automerger Merge Worker
Browse files

Merge "Add bumble test for scanning with service data filter." into main am:...

Merge "Add bumble test for scanning with service data filter." into main am: b0acd0f4 am: 96a9eb24

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



Change-Id: I75cbb38c58b9a65d2277bd8a193b440dddf64cea
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents c0405986 96a9eb24
Loading
Loading
Loading
Loading
+7 −7
Original line number Diff line number Diff line
@@ -256,8 +256,8 @@ import java.util.UUID;
                serviceDataMask = new byte[serviceData.length];
                Arrays.fill(serviceDataMask, (byte) 0xFF);
            }
            serviceData = concate(serviceDataUuid, serviceData);
            serviceDataMask = concate(serviceDataUuid, serviceDataMask);
            serviceData = concatenate(serviceDataUuid, serviceData);
            serviceDataMask = concatenate(serviceDataUuid, serviceDataMask);
            if (serviceData != null && serviceDataMask != null) {
                addServiceData(serviceData, serviceDataMask);
            }
@@ -293,7 +293,7 @@ import java.util.UUID;
        }
    }

    private byte[] concate(ParcelUuid serviceDataUuid, byte[] serviceData) {
    private byte[] concatenate(ParcelUuid serviceDataUuid, byte[] serviceData) {
        byte[] uuid = BluetoothUuid.uuidToBytes(serviceDataUuid);

        int dataLen = uuid.length + (serviceData == null ? 0 : serviceData.length);
@@ -301,11 +301,11 @@ import java.util.UUID;
        if (dataLen > MAX_LEN_PER_FIELD) {
            return null;
        }
        byte[] concated = new byte[dataLen];
        System.arraycopy(uuid, 0, concated, 0, uuid.length);
        byte[] concatenated = new byte[dataLen];
        System.arraycopy(uuid, 0, concatenated, 0, uuid.length);
        if (serviceData != null) {
            System.arraycopy(serviceData, 0, concated, uuid.length, serviceData.length);
            System.arraycopy(serviceData, 0, concatenated, uuid.length, serviceData.length);
        }
        return concated;
        return concatenated;
    }
}
+75 −21
Original line number Diff line number Diff line
@@ -41,11 +41,12 @@ import android.os.ParcelUuid;
import android.util.Log;

import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;

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.Rule;
import org.junit.Test;
@@ -63,7 +64,7 @@ import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;

@RunWith(AndroidJUnit4.class)
@RunWith(TestParameterInjector.class)
public class LeScanningTest {
    private static final String TAG = "LeScanningTest";
    private static final int TIMEOUT_SCANNING_MS = 2000;
@@ -71,6 +72,8 @@ public class LeScanningTest {
    private static final String TEST_ADDRESS_RANDOM_STATIC = "F0:43:A8:23:10:11";
    private static final String ACTION_DYNAMIC_RECEIVER_SCAN_RESULT =
            "android.bluetooth.test.ACTION_DYNAMIC_RECEIVER_SCAN_RESULT";
    private static final byte[] TEST_SERVICE_DATA = {(byte) 0xAA, (byte) 0xBB, (byte) 0xCC};
    private static final String TEST_UUID_SUFFIX = "-0000-1000-8000-00805f9b34fb";

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

@@ -92,7 +95,8 @@ public class LeScanningTest {
                        .build();

        List<ScanResult> results =
                startScanning(scanFilter, ScanSettings.CALLBACK_TYPE_ALL_MATCHES);
                startScanning(
                        scanFilter, ScanSettings.CALLBACK_TYPE_ALL_MATCHES, /* isLegacy= */ true);

        assertThat(results).isNotNull();
        assertThat(results.get(0).getScanRecord().getServiceUuids().get(0))
@@ -114,7 +118,8 @@ public class LeScanningTest {
                        .build();

        List<ScanResult> results =
                startScanning(scanFilter, ScanSettings.CALLBACK_TYPE_ALL_MATCHES);
                startScanning(
                        scanFilter, ScanSettings.CALLBACK_TYPE_ALL_MATCHES, /* isLegacy= */ true);

        assertThat(results).isNotEmpty();
        assertThat(results.get(0).getDevice().getAddress()).isEqualTo(TEST_ADDRESS_RANDOM_STATIC);
@@ -295,7 +300,7 @@ public class LeScanningTest {
                AdvertiseRequest.newBuilder()
                        .setConnectable(false)
                        .setOwnAddressType(OwnAddressType.PUBLIC);
        advertiseWithBumble(requestBuilder);
        advertiseWithBumble(requestBuilder, true);

        ScanFilter scanFilter =
                new ScanFilter.Builder()
@@ -303,7 +308,8 @@ public class LeScanningTest {
                        .build();

        List<ScanResult> results =
                startScanning(scanFilter, ScanSettings.CALLBACK_TYPE_ALL_MATCHES);
                startScanning(
                        scanFilter, ScanSettings.CALLBACK_TYPE_ALL_MATCHES, /* isLegacy= */ true);

        assertThat(results).isNotNull();
        assertThat(results.get(0).isConnectable()).isFalse();
@@ -324,7 +330,7 @@ public class LeScanningTest {
                        .setConnectable(false)
                        .setOwnAddressType(OwnAddressType.PUBLIC)
                        .setScanResponseData(scanResponse);
        advertiseWithBumble(requestBuilder);
        advertiseWithBumble(requestBuilder, true);

        ScanFilter scanFilter =
                new ScanFilter.Builder()
@@ -332,7 +338,8 @@ public class LeScanningTest {
                        .build();

        List<ScanResult> results =
                startScanning(scanFilter, ScanSettings.CALLBACK_TYPE_ALL_MATCHES);
                startScanning(
                        scanFilter, ScanSettings.CALLBACK_TYPE_ALL_MATCHES, /* isLegacy= */ true);

        assertThat(results).isNotNull();
        assertThat(results.get(0).isConnectable()).isFalse();
@@ -340,7 +347,46 @@ public class LeScanningTest {
                .isEqualTo(payload);
    }

    private List<ScanResult> startScanning(ScanFilter scanFilter, int callbackType) {
    @Test
    public void startBleScan_withServiceData() {
        advertiseWithBumbleWithServiceData();

        ScanFilter scanFilter =
                new ScanFilter.Builder()
                        .setServiceData(ParcelUuid.fromString(TEST_UUID_STRING), TEST_SERVICE_DATA)
                        .build();

        List<ScanResult> results =
                startScanning(
                        scanFilter, ScanSettings.CALLBACK_TYPE_ALL_MATCHES, /* isLegacy= */ false);

        assertThat(results).isNotNull();
        assertThat(results.get(0).getScanRecord().getServiceUuids().get(0))
                .isEqualTo(ParcelUuid.fromString(TEST_UUID_STRING));
    }

    // Test against UUIDs that are close to TEST_UUID_STRING, one that has a few bits unset and one
    // that has an extra bit set.
    @Test
    public void startBleScan_withServiceData_uuidDoesntMatch(
            @TestParameter({"00001800", "00001815"}) String uuid) {
        advertiseWithBumbleWithServiceData();

        ScanFilter scanFilter =
                new ScanFilter.Builder()
                        .setServiceData(
                                ParcelUuid.fromString(uuid + TEST_UUID_SUFFIX), TEST_SERVICE_DATA)
                        .build();

        List<ScanResult> results =
                startScanning(
                        scanFilter, ScanSettings.CALLBACK_TYPE_ALL_MATCHES, /* isLegacy= */ false);

        assertThat(results).isNull();
    }

    private List<ScanResult> startScanning(
            ScanFilter scanFilter, int callbackType, boolean isLegacy) {
        CompletableFuture<List<ScanResult>> future = new CompletableFuture<>();
        List<ScanResult> scanResults = new ArrayList<>();

@@ -348,6 +394,7 @@ public class LeScanningTest {
                new ScanSettings.Builder()
                        .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
                        .setCallbackType(callbackType)
                        .setLegacy(isLegacy)
                        .build();

        ScanCallback scanCallback =
@@ -366,14 +413,9 @@ public class LeScanningTest {
                                        + ", service uuids: "
                                        + result.getScanRecord().getServiceUuids());

                        if (callbackType == ScanSettings.CALLBACK_TYPE_ALL_MATCHES) {
                            if (scanResults.size() < 2) {
                                scanResults.add(result);
                            } else {
                                future.complete(scanResults);
                            }
                        } else {
                        scanResults.add(result);
                        if (callbackType != ScanSettings.CALLBACK_TYPE_ALL_MATCHES
                                || scanResults.size() > 1) {
                            future.complete(scanResults);
                        }
                    }
@@ -395,6 +437,19 @@ public class LeScanningTest {
        return result;
    }

    private void advertiseWithBumbleWithServiceData() {
        AdvertiseRequest.Builder requestBuilder =
                AdvertiseRequest.newBuilder().setOwnAddressType(OwnAddressType.PUBLIC);

        HostProto.DataTypes.Builder dataTypeBuilder = HostProto.DataTypes.newBuilder();
        dataTypeBuilder.addCompleteServiceClassUuids128(TEST_UUID_STRING);
        dataTypeBuilder.putServiceDataUuid128(
                TEST_UUID_STRING, ByteString.copyFrom(TEST_SERVICE_DATA));
        requestBuilder.setData(dataTypeBuilder.build());

        advertiseWithBumble(requestBuilder, false);
    }

    private void advertiseWithBumble(String serviceUuid, OwnAddressType addressType) {
        AdvertiseRequest.Builder requestBuilder =
                AdvertiseRequest.newBuilder().setOwnAddressType(addressType);
@@ -405,12 +460,11 @@ public class LeScanningTest {
            requestBuilder.setData(dataTypeBuilder.build());
        }

        advertiseWithBumble(requestBuilder);
        advertiseWithBumble(requestBuilder, true);
    }

    private void advertiseWithBumble(AdvertiseRequest.Builder requestBuilder) {
        // Bumble currently only supports legacy advertising.
        requestBuilder.setLegacy(true);
    private void advertiseWithBumble(AdvertiseRequest.Builder requestBuilder, boolean isLegacy) {
        requestBuilder.setLegacy(isLegacy);
        // Collect and ignore responses.
        StreamObserverSpliterator<AdvertiseResponse> responseObserver =
                new StreamObserverSpliterator<>();