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

Commit cd34df77 authored by Kyunglyul Hyun's avatar Kyunglyul Hyun
Browse files

Clean up restricted handles on disconnection

Restricted handles were not cleaned up so
that it could raise exception when a BT device
is connected after a HID device is disconnected.

Bug: 322580271
Bug: 322509603
Test: atest GattServiceTest w/ and w/o the flag

Change-Id: I24edf15eab9dd5bb53a43d0ceeb6a39316488d4e
parent 74609e68
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -284,7 +284,7 @@ public class GattService extends ProfileService {
    /**
     * Set of restricted (which require a BLUETOOTH_PRIVILEGED permission) handles per connectionId.
     */
    private final Map<Integer, Set<Integer>> mRestrictedHandles = new HashMap<>();
    @VisibleForTesting final Map<Integer, Set<Integer>> mRestrictedHandles = new HashMap<>();

    /**
     * HashMap used to synchronize writeCharacteristic calls mapping remote device address to
@@ -397,6 +397,9 @@ public class GattService extends ProfileService {
        mScannerMap.clear();
        mAdvertiserMap.clear();
        mClientMap.clear();
        if (Flags.gattCleanupRestrictedHandles()) {
            mRestrictedHandles.clear();
        }
        mServerMap.clear();
        mHandleMap.clear();
        mReliableQueue.clear();
@@ -2281,6 +2284,10 @@ public class GattService extends ProfileService {
        mClientMap.removeConnection(clientIf, connId);
        ClientMap.App app = mClientMap.getById(clientIf);

        if (Flags.gattCleanupRestrictedHandles()) {
            mRestrictedHandles.remove(connId);
        }

        // Remove AtomicBoolean representing permit if no other connections rely on this remote device.
        if (!mClientMap.getConnectedDevices().contains(address)) {
            synchronized (mPermits) {
+47 −0
Original line number Diff line number Diff line
@@ -47,6 +47,8 @@ import android.os.RemoteException;
import android.os.WorkSource;

import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.rule.ServiceTestRule;
@@ -107,6 +109,9 @@ public class GattServiceTest {

    @Rule public final ServiceTestRule mServiceRule = new ServiceTestRule();

    @Rule
    public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();

    private BluetoothDevice mDevice;
    private BluetoothAdapter mAdapter;
    private AttributionSource mAttributionSource;
@@ -885,4 +890,46 @@ public class GattServiceTest {
                        BluetoothProfile.STATE_CONNECTING,
                        BluetoothProfile.STATE_CONNECTED);
    }

    @RequiresFlagsEnabled(Flags.FLAG_GATT_CLEANUP_RESTRICTED_HANDLES)
    @Test
    public void restrictedHandles() throws Exception {
        int clientIf = 1;
        int connId = 1;
        ArrayList<GattDbElement> db = new ArrayList<>();

        GattService.ClientMap.App app = mock(GattService.ClientMap.App.class);
        IBluetoothGattCallback callback = mock(IBluetoothGattCallback.class);

        doReturn(app).when(mClientMap).getByConnId(connId);
        app.callback = callback;

        GattDbElement hidService =
                GattDbElement.createPrimaryService(
                        UUID.fromString("00001812-0000-1000-8000-00805F9B34FB"));
        hidService.id = 1;

        GattDbElement hidInfoChar =
                GattDbElement.createCharacteristic(
                        UUID.fromString("00002A4A-0000-1000-8000-00805F9B34FB"), 0, 0);
        hidInfoChar.id = 2;

        GattDbElement randomChar =
                GattDbElement.createCharacteristic(
                        UUID.fromString("0000FFFF-0000-1000-8000-00805F9B34FB"), 0, 0);
        randomChar.id = 3;

        db.add(hidService);
        db.add(hidInfoChar);
        db.add(randomChar);

        mService.onGetGattDb(connId, db);
        // HID characteristics should be restricted
        assertThat(mService.mRestrictedHandles.get(connId)).contains(hidInfoChar.id);
        assertThat(mService.mRestrictedHandles.get(connId)).doesNotContain(randomChar.id);

        mService.onDisconnected(
                clientIf, connId, BluetoothGatt.GATT_SUCCESS, REMOTE_DEVICE_ADDRESS);
        assertThat(mService.mRestrictedHandles).doesNotContainKey(connId);
    }
}