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

Commit 76fa07ec authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Improve performance of GattService.permissionCheck by removing...

Merge "Improve performance of GattService.permissionCheck by removing on-demand handleId to UUID translation."
parents 8334f7fd 85f7f1a6
Loading
Loading
Loading
Loading
+49 −48
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@ import com.android.bluetooth.btservice.ProfileService;
import com.android.bluetooth.util.NumberUtils;
import com.android.internal.annotations.VisibleForTesting;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -98,6 +99,9 @@ public class GattService extends ProfileService {

    private static final int ET_LEGACY_MASK = 0x10;

    private static final UUID HID_SERVICE_UUID =
            UUID.fromString("00001812-0000-1000-8000-00805F9B34FB");

    private static final UUID[] HID_UUIDS = {
            UUID.fromString("00002A4A-0000-1000-8000-00805F9B34FB"),
            UUID.fromString("00002A4B-0000-1000-8000-00805F9B34FB"),
@@ -108,9 +112,8 @@ public class GattService extends ProfileService {
    private static final UUID ANDROID_TV_REMOTE_SERVICE_UUID =
            UUID.fromString("AB5E0001-5A21-4F05-BC7D-AF01F617B664");

    private static final UUID[] FIDO_UUIDS = {
            UUID.fromString("0000FFFD-0000-1000-8000-00805F9B34FB") // U2F
    };
    private static final UUID FIDO_SERVICE_UUID =
            UUID.fromString("0000FFFD-0000-1000-8000-00805F9B34FB"); // U2F

    /**
     * Keep the arguments passed in for the PendingIntent.
@@ -160,13 +163,17 @@ public class GattService extends ProfileService {
    private int mMaxScanFilters;

    private static final int NUM_SCAN_EVENTS_KEPT = 20;

    /**
     * Internal list of scan events to use with the proto
     */
    private final ArrayList<BluetoothMetricsProto.ScanEvent> mScanEvents =
            new ArrayList<>(NUM_SCAN_EVENTS_KEPT);
    private final ArrayDeque<BluetoothMetricsProto.ScanEvent> mScanEvents =
            new ArrayDeque<>(NUM_SCAN_EVENTS_KEPT);

    private final Map<Integer, List<BluetoothGattService>> mGattClientDatabases = new HashMap<>();
    /**
     * Set of restricted (which require a BLUETOOTH_PRIVILEGED permission) handles per connectionId.
     */
    private final Map<Integer, Set<Integer>> mRestrictedHandles = new HashMap<>();

    private BluetoothAdapter mAdapter;
    private AdvertiseManager mAdvertiseManager;
@@ -277,36 +284,20 @@ public class GattService extends ProfileService {
        sGattService = instance;
    }

    boolean permissionCheck(UUID uuid) {
        return !(isRestrictedCharUuid(uuid) && (0 != checkCallingOrSelfPermission(
                BLUETOOTH_PRIVILEGED)));
    private boolean permissionCheck(UUID characteristicUuid) {
        return !isHidCharUuid(characteristicUuid)
                || (checkCallingOrSelfPermission(BLUETOOTH_PRIVILEGED)
                        == PERMISSION_GRANTED);
    }

    boolean permissionCheck(int connId, int handle) {
        List<BluetoothGattService> db = mGattClientDatabases.get(connId);
        if (db == null) {
    private boolean permissionCheck(int connId, int handle) {
        Set<Integer> restrictedHandles = mRestrictedHandles.get(connId);
        if (restrictedHandles == null || !restrictedHandles.contains(handle)) {
            return true;
        }

        for (BluetoothGattService service : db) {
            for (BluetoothGattCharacteristic characteristic : service.getCharacteristics()) {
                if (handle == characteristic.getInstanceId()) {
                    return !((isRestrictedCharUuid(characteristic.getUuid())
                            || isRestrictedSrvcUuid(service.getUuid()))
                            && (0 != checkCallingOrSelfPermission(BLUETOOTH_PRIVILEGED)));
                }

                for (BluetoothGattDescriptor descriptor : characteristic.getDescriptors()) {
                    if (handle == descriptor.getInstanceId()) {
                        return !((isRestrictedCharUuid(characteristic.getUuid())
                                || isRestrictedSrvcUuid(service.getUuid())) && (0
                                != checkCallingOrSelfPermission(BLUETOOTH_PRIVILEGED)));
                    }
                }
            }
        }

        return true;
        return (checkCallingOrSelfPermission(BLUETOOTH_PRIVILEGED)
                == PERMISSION_GRANTED);
    }

    @Override
@@ -1309,9 +1300,13 @@ public class GattService extends ProfileService {
        }

        List<BluetoothGattService> dbOut = new ArrayList<BluetoothGattService>();
        Set<Integer> restrictedIds = new HashSet<>();

        BluetoothGattService currSrvc = null;
        BluetoothGattCharacteristic currChar = null;
        boolean isRestrictedSrvc = false;
        boolean isHidSrvc = false;
        boolean isRestrictedChar = false;

        for (GattDbElement el : db) {
            switch (el.type) {
@@ -1323,6 +1318,12 @@ public class GattService extends ProfileService {

                    currSrvc = new BluetoothGattService(el.uuid, el.id, el.type);
                    dbOut.add(currSrvc);
                    isRestrictedSrvc =
                            isFidoSrvcUuid(el.uuid) || isAndroidTvRemoteSrvcUuid(el.uuid);
                    isHidSrvc = isHidSrvcUuid(el.uuid);
                    if (isRestrictedSrvc) {
                        restrictedIds.add(el.id);
                    }
                    break;

                case GattDbElement.TYPE_CHARACTERISTIC:
@@ -1332,6 +1333,10 @@ public class GattService extends ProfileService {

                    currChar = new BluetoothGattCharacteristic(el.uuid, el.id, el.properties, 0);
                    currSrvc.addCharacteristic(currChar);
                    isRestrictedChar = isRestrictedSrvc || (isHidSrvc && isHidCharUuid(el.uuid));
                    if (isRestrictedChar) {
                        restrictedIds.add(el.id);
                    }
                    break;

                case GattDbElement.TYPE_DESCRIPTOR:
@@ -1340,6 +1345,9 @@ public class GattService extends ProfileService {
                    }

                    currChar.addDescriptor(new BluetoothGattDescriptor(el.uuid, el.id, 0));
                    if (isRestrictedChar) {
                        restrictedIds.add(el.id);
                    }
                    break;

                case GattDbElement.TYPE_INCLUDED_SERVICE:
@@ -1358,8 +1366,10 @@ public class GattService extends ProfileService {
            }
        }

        if (!restrictedIds.isEmpty()) {
            mRestrictedHandles.put(connId, restrictedIds);
        }
        // Search is complete when there was error, or nothing more to process
        mGattClientDatabases.put(connId, dbOut);
        app.callback.onSearchComplete(address, dbOut, 0 /* status */);
    }

@@ -2995,15 +3005,11 @@ public class GattService extends ProfileService {
     * Private functions
     *************************************************************************/

    private boolean isRestrictedCharUuid(final UUID charUuid) {
        return isHidUuid(charUuid);
    private boolean isHidSrvcUuid(final UUID uuid) {
        return HID_SERVICE_UUID.equals(uuid);
    }

    private boolean isRestrictedSrvcUuid(final UUID srvcUuid) {
        return isFidoUUID(srvcUuid) || isAndroidTvRemoteSrvcUUID(srvcUuid);
    }

    private boolean isHidUuid(final UUID uuid) {
    private boolean isHidCharUuid(final UUID uuid) {
        for (UUID hidUuid : HID_UUIDS) {
            if (hidUuid.equals(uuid)) {
                return true;
@@ -3012,17 +3018,12 @@ public class GattService extends ProfileService {
        return false;
    }

    private boolean isAndroidTvRemoteSrvcUUID(final UUID uuid) {
    private boolean isAndroidTvRemoteSrvcUuid(final UUID uuid) {
        return ANDROID_TV_REMOTE_SERVICE_UUID.equals(uuid);
    }

    private boolean isFidoUUID(final UUID uuid) {
        for (UUID fidoUuid : FIDO_UUIDS) {
            if (fidoUuid.equals(uuid)) {
                return true;
            }
        }
        return false;
    private boolean isFidoSrvcUuid(final UUID uuid) {
        return FIDO_SERVICE_UUID.equals(uuid);
    }

    private int getDeviceType(BluetoothDevice device) {
@@ -3174,7 +3175,7 @@ public class GattService extends ProfileService {
    void addScanEvent(BluetoothMetricsProto.ScanEvent event) {
        synchronized (mScanEvents) {
            if (mScanEvents.size() == NUM_SCAN_EVENTS_KEPT) {
                mScanEvents.remove(0);
                mScanEvents.remove();
            }
            mScanEvents.add(event);
        }