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

Commit e2cf3a88 authored by Himanshu Rawat's avatar Himanshu Rawat Committed by Gerrit Code Review
Browse files

Merge "Move service discovery test cases into a separate folder" into main

parents ce649c40 7420ea08
Loading
Loading
Loading
Loading
+0 −116
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package android.bluetooth;

import static com.google.common.truth.Truth.assertThat;

import android.bluetooth.test_utils.EnableBluetoothRule;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.ParcelUuid;

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

import com.android.compatibility.common.util.AdoptShellPermissionsRule;

import com.google.common.util.concurrent.SettableFuture;
import com.google.protobuf.ByteString;

import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import pandora.HostProto.ConnectRequest;

import java.util.Arrays;
import java.util.List;

/** Test cases for {@link ServiceDiscoveryManager}. */
@RunWith(AndroidJUnit4.class)
public class SdpClientTest {
    private static final String TAG = "SdpClientTest";

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

    private SettableFuture<List<ParcelUuid>> mFutureIntent;

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

    @Rule(order = 1)
    public final PandoraDevice mBumble = new PandoraDevice();

    @Rule(order = 2)
    public final EnableBluetoothRule enableBluetoothRule = new EnableBluetoothRule(false, true);

    private BroadcastReceiver mConnectionStateReceiver =
            new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    if (BluetoothDevice.ACTION_UUID.equals(intent.getAction())) {
                        ParcelUuid[] parcelUuids =
                                intent.getParcelableArrayExtra(
                                        BluetoothDevice.EXTRA_UUID, ParcelUuid.class);
                        if (parcelUuids != null) {
                            mFutureIntent.set(Arrays.asList(parcelUuids));
                        }
                    }
                }
            };

    @Before
    public void setup() {
        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_UUID);
        mContext.registerReceiver(mConnectionStateReceiver, filter);
    }

    @After
    public void tearDown() {
        mContext.unregisterReceiver(mConnectionStateReceiver);
    }

    @Test
    public void remoteConnectServiceDiscoveryTest() throws Exception {
        mFutureIntent = SettableFuture.create();

        String local_addr = mAdapter.getAddress();
        byte[] local_bytes_addr = Utils.addressBytesFromString(local_addr);

        mBumble.hostBlocking()
                .connect(
                        ConnectRequest.newBuilder()
                                .setAddress(ByteString.copyFrom(local_bytes_addr))
                                .build());

        BluetoothDevice device = mBumble.getRemoteDevice();

        assertThat(device.fetchUuidsWithSdp()).isTrue();

        assertThat(mFutureIntent.get())
                .containsAtLeast(
                        BluetoothUuid.HFP,
                        BluetoothUuid.A2DP_SOURCE,
                        BluetoothUuid.A2DP_SINK,
                        BluetoothUuid.AVRCP);
    }
}
+0 −132
Original line number Diff line number Diff line
@@ -39,7 +39,6 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.ParcelUuid;
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.util.Log;
@@ -47,7 +46,6 @@ import android.util.Log;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;

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

import io.grpc.stub.StreamObserver;
@@ -66,7 +64,6 @@ import org.mockito.MockitoAnnotations;
import org.mockito.hamcrest.MockitoHamcrest;

import pandora.GattProto;
import pandora.HostProto;
import pandora.HostProto.AdvertiseRequest;
import pandora.HostProto.AdvertiseResponse;
import pandora.HostProto.OwnAddressType;
@@ -381,135 +378,6 @@ public class PairingTest {
        unregisterIntentActions(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
    }

    /**
     * Ensure that successful BR/EDR service discovery results in a single ACTION_UUID intent
     *
     * <p>Prerequisites:
     *
     * <ol>
     *   <li>Bumble and Android are not bonded
     *   <li>Bumble has BR/EDR services
     * </ol>
     *
     * <p>Steps:
     *
     * <ol>
     *   <li>Bumble is discoverable and connectable over BR/EDR
     *   <li>Android connects to Bumble over BR/EDR
     *   <li>Android starts service discovery
     * </ol>
     *
     * Expectation: A single ACTION_UUID intent is received The ACTION_UUID intent is not empty
     */
    @Test
    @RequiresFlagsEnabled({Flags.FLAG_PREVENT_DUPLICATE_UUID_INTENT})
    public void testServiceDiscoveryBredr_SingleIntent() {
        // Setup intent filters
        registerIntentActions(
                BluetoothDevice.ACTION_UUID,
                BluetoothDevice.ACTION_ACL_CONNECTED,
                BluetoothDevice.ACTION_ACL_DISCONNECTED);

        // Start GATT service discovery, this will establish BR/EDR ACL
        assertThat(mBumbleDevice.fetchUuidsWithSdp(BluetoothDevice.TRANSPORT_BREDR)).isTrue();

        // Wait for connection on Android
        verifyIntentReceived(
                hasAction(BluetoothDevice.ACTION_ACL_CONNECTED),
                hasExtra(BluetoothDevice.EXTRA_TRANSPORT, BluetoothDevice.TRANSPORT_BREDR));

        // Wait for the service discovery to complete on Android
        verifyIntentReceived(hasAction(BluetoothDevice.ACTION_UUID));

        verifyIntentReceived(
                hasAction(BluetoothDevice.ACTION_ACL_DISCONNECTED),
                hasExtra(BluetoothDevice.EXTRA_TRANSPORT, BluetoothDevice.TRANSPORT_BREDR));

        // Ensure that no other ACTION_UUID intent is received
        verifyNoMoreInteractions(mReceiver);

        unregisterIntentActions(
                BluetoothDevice.ACTION_UUID,
                BluetoothDevice.ACTION_ACL_CONNECTED,
                BluetoothDevice.ACTION_ACL_DISCONNECTED);
    }

    /**
     * Ensure that successful LE service discovery results in a single ACTION_UUID intent
     *
     * <p>Prerequisites:
     *
     * <ol>
     *   <li>Bumble and Android are not bonded
     *   <li>Bumble has GATT services in addition to GAP and GATT services
     * </ol>
     *
     * <p>Steps:
     *
     * <ol>
     *   <li>Bumble is discoverable and connectable over LE
     *   <li>Android connects to Bumble over LE
     *   <li>Android starts GATT service discovery
     * </ol>
     *
     * Expectation: A single ACTION_UUID intent is received The ACTION_UUID intent is not empty
     */
    @Test
    @RequiresFlagsEnabled({Flags.FLAG_PREVENT_DUPLICATE_UUID_INTENT})
    public void testServiceDiscoveryLe_SingleIntent() {
        // Setup intent filters
        registerIntentActions(
                BluetoothDevice.ACTION_UUID,
                BluetoothDevice.ACTION_ACL_CONNECTED,
                BluetoothDevice.ACTION_ACL_DISCONNECTED);

        // Register some services on Bumble
        for (int i = 0; i < 6; i++) {
            mBumble.gattBlocking()
                    .registerService(
                            GattProto.RegisterServiceRequest.newBuilder()
                                    .setService(
                                            GattProto.GattServiceParams.newBuilder()
                                                    .setUuid(BATTERY_UUID.toString())
                                                    .build())
                                    .build());
        }

        // Make Bumble connectable
        mBumble.hostBlocking()
                .advertise(
                        HostProto.AdvertiseRequest.newBuilder()
                                .setLegacy(true)
                                .setConnectable(true)
                                .setOwnAddressType(HostProto.OwnAddressType.PUBLIC)
                                .build());

        // Start GATT service discovery, this will establish LE ACL
        assertThat(mBumbleDevice.fetchUuidsWithSdp(BluetoothDevice.TRANSPORT_LE)).isTrue();

        // Wait for connection on Android
        verifyIntentReceived(
                hasAction(BluetoothDevice.ACTION_ACL_CONNECTED),
                hasExtra(BluetoothDevice.EXTRA_TRANSPORT, BluetoothDevice.TRANSPORT_LE));

        // Wait for GATT service discovery to complete on Android
        verifyIntentReceived(
                hasAction(BluetoothDevice.ACTION_UUID),
                hasExtra(BluetoothDevice.EXTRA_UUID, Matchers.hasItemInArray(BATTERY_UUID)));

        verifyIntentReceived(
                hasAction(BluetoothDevice.ACTION_ACL_DISCONNECTED),
                hasExtra(BluetoothDevice.EXTRA_TRANSPORT, BluetoothDevice.TRANSPORT_LE));

        // Ensure that no other ACTION_UUID intent is received
        verifyNoMoreInteractions(mReceiver);

        unregisterIntentActions(
                BluetoothDevice.ACTION_UUID,
                BluetoothDevice.ACTION_ACL_CONNECTED,
                BluetoothDevice.ACTION_ACL_DISCONNECTED);
    }

    /* Starts outgoing GATT service discovery and incoming LE pairing in parallel */
    private StreamObserverSpliterator<SecureResponse>
            helper_OutgoingGattServiceDiscoveryWithIncomingLePairing() {
+3 −0
Original line number Diff line number Diff line
# Bug component: 27441
# Project owners
cmanton@google.com
+400 −0

File added.

Preview size limit exceeded, changes collapsed.