Loading android/app/src/com/android/bluetooth/gatt/GattService.java +49 −48 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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"), Loading @@ -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. Loading Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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) { Loading @@ -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: Loading @@ -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: Loading @@ -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: Loading @@ -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 */); } Loading Loading @@ -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; Loading @@ -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) { Loading Loading @@ -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); } Loading Loading
android/app/src/com/android/bluetooth/gatt/GattService.java +49 −48 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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"), Loading @@ -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. Loading Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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) { Loading @@ -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: Loading @@ -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: Loading @@ -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: Loading @@ -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 */); } Loading Loading @@ -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; Loading @@ -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) { Loading Loading @@ -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); } Loading