diff options
33 files changed, 697 insertions, 695 deletions
diff --git a/android/app/jni/com_android_bluetooth_gatt.cpp b/android/app/jni/com_android_bluetooth_gatt.cpp index acd609f8bd..be0922c8fc 100644 --- a/android/app/jni/com_android_bluetooth_gatt.cpp +++ b/android/app/jni/com_android_bluetooth_gatt.cpp @@ -2353,7 +2353,11 @@ static AdvertiseParameters parseParams(JNIEnv* env, jobject i) { p.secondary_advertising_phy = secondaryPhy; p.scan_request_notification_enable = false; p.own_address_type = ownAddressType; - p.peer_address = str2addr(env, peerAddress); + if (peerAddress == nullptr) { + p.peer_address = RawAddress::kEmpty; + } else { + p.peer_address = str2addr(env, peerAddress); + } p.peer_address_type = peerAddressType; p.discoverable = isDiscoverable; return p; diff --git a/android/app/src/com/android/bluetooth/Utils.java b/android/app/src/com/android/bluetooth/Utils.java index ce23339f0b..3a681bb7e7 100644 --- a/android/app/src/com/android/bluetooth/Utils.java +++ b/android/app/src/com/android/bluetooth/Utils.java @@ -624,6 +624,13 @@ public final class Utils { return checkPermissionForDataDelivery(context, BLUETOOTH_CONNECT, source, message); } + @SuppressLint("AndroidFrameworkRequiresPermission") // This method enforce the permission + @RequiresPermission(BLUETOOTH_CONNECT) + public static boolean checkConnectPermissionForDataDelivery( + Context context, AttributionSource source, String tag, String method) { + return checkConnectPermissionForDataDelivery(context, source, tag + "." + method + "()"); + } + /** * Returns true if the BLUETOOTH_SCAN permission is granted for the calling app. Returns false * if the result is a soft denial. Throws SecurityException if the result is a hard denial. @@ -646,8 +653,9 @@ public final class Utils { @SuppressLint("AndroidFrameworkRequiresPermission") // This method enforce the permission @RequiresPermission(BLUETOOTH_SCAN) public static boolean checkScanPermissionForDataDelivery( - Context context, AttributionSource source, String message) { - return checkPermissionForDataDelivery(context, BLUETOOTH_SCAN, source, message); + Context context, AttributionSource source, String tag, String method) { + return checkPermissionForDataDelivery( + context, BLUETOOTH_SCAN, source, tag + "." + method + "()"); } /** diff --git a/android/app/src/com/android/bluetooth/bass_client/BassClientService.java b/android/app/src/com/android/bluetooth/bass_client/BassClientService.java index 2b2b495ce4..edf88f9331 100644 --- a/android/app/src/com/android/bluetooth/bass_client/BassClientService.java +++ b/android/app/src/com/android/bluetooth/bass_client/BassClientService.java @@ -4876,7 +4876,8 @@ public class BassClientService extends ProfileService { if (!Utils.checkServiceAvailable(service, TAG) || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG) - || !Utils.checkScanPermissionForDataDelivery(service, source, TAG)) { + || !Utils.checkScanPermissionForDataDelivery( + service, source, TAG, "getServiceAndEnforceScan")) { return null; } diff --git a/android/app/src/com/android/bluetooth/btservice/AdapterService.java b/android/app/src/com/android/bluetooth/btservice/AdapterService.java index 0eeeb7f6bd..9bec63769d 100644 --- a/android/app/src/com/android/bluetooth/btservice/AdapterService.java +++ b/android/app/src/com/android/bluetooth/btservice/AdapterService.java @@ -314,10 +314,10 @@ public class AdapterService extends Service { private BluetoothSocketManagerBinder mBluetoothSocketManagerBinder; private BluetoothKeystoreService mBluetoothKeystoreService; - private A2dpService mA2dpService; - private A2dpSinkService mA2dpSinkService; private HeadsetService mHeadsetService; private HeadsetClientService mHeadsetClientService; + private A2dpService mA2dpService; + private A2dpSinkService mA2dpSinkService; private BluetoothMapService mMapService; private MapClientService mMapClientService; private HidDeviceService mHidDeviceService; @@ -1762,14 +1762,6 @@ public class AdapterService extends Service { * @return false if one of profile is enabled or disabled, true otherwise */ boolean isAllProfilesUnknown(BluetoothDevice device) { - if (mA2dpService != null - && mA2dpService.getConnectionPolicy(device) != CONNECTION_POLICY_UNKNOWN) { - return false; - } - if (mA2dpSinkService != null - && mA2dpSinkService.getConnectionPolicy(device) != CONNECTION_POLICY_UNKNOWN) { - return false; - } if (mHeadsetService != null && mHeadsetService.getConnectionPolicy(device) != CONNECTION_POLICY_UNKNOWN) { return false; @@ -1778,6 +1770,14 @@ public class AdapterService extends Service { && mHeadsetClientService.getConnectionPolicy(device) != CONNECTION_POLICY_UNKNOWN) { return false; } + if (mA2dpService != null + && mA2dpService.getConnectionPolicy(device) != CONNECTION_POLICY_UNKNOWN) { + return false; + } + if (mA2dpSinkService != null + && mA2dpSinkService.getConnectionPolicy(device) != CONNECTION_POLICY_UNKNOWN) { + return false; + } if (mMapClientService != null && mMapClientService.getConnectionPolicy(device) != CONNECTION_POLICY_UNKNOWN) { return false; @@ -1837,18 +1837,7 @@ public class AdapterService extends Service { Log.i(TAG, "connectEnabledProfiles: Connecting Coordinated Set Profile"); mCsipSetCoordinatorService.connect(device); } - if (mA2dpService != null - && isProfileSupported(device, BluetoothProfile.A2DP) - && mA2dpService.getConnectionPolicy(device) > CONNECTION_POLICY_FORBIDDEN) { - Log.i(TAG, "connectEnabledProfiles: Connecting A2dp"); - mA2dpService.connect(device); - } - if (mA2dpSinkService != null - && isProfileSupported(device, BluetoothProfile.A2DP_SINK) - && mA2dpSinkService.getConnectionPolicy(device) > CONNECTION_POLICY_FORBIDDEN) { - Log.i(TAG, "connectEnabledProfiles: Connecting A2dp Sink"); - mA2dpSinkService.connect(device); - } + // Order matters, some devices do not accept A2DP connection before HFP connection if (mHeadsetService != null && isProfileSupported(device, BluetoothProfile.HEADSET) && mHeadsetService.getConnectionPolicy(device) > CONNECTION_POLICY_FORBIDDEN) { @@ -1862,6 +1851,18 @@ public class AdapterService extends Service { Log.i(TAG, "connectEnabledProfiles: Connecting HFP"); mHeadsetClientService.connect(device); } + if (mA2dpService != null + && isProfileSupported(device, BluetoothProfile.A2DP) + && mA2dpService.getConnectionPolicy(device) > CONNECTION_POLICY_FORBIDDEN) { + Log.i(TAG, "connectEnabledProfiles: Connecting A2dp"); + mA2dpService.connect(device); + } + if (mA2dpSinkService != null + && isProfileSupported(device, BluetoothProfile.A2DP_SINK) + && mA2dpSinkService.getConnectionPolicy(device) > CONNECTION_POLICY_FORBIDDEN) { + Log.i(TAG, "connectEnabledProfiles: Connecting A2dp Sink"); + mA2dpSinkService.connect(device); + } if (mMapClientService != null && isProfileSupported(device, BluetoothProfile.MAP_CLIENT) && mMapClientService.getConnectionPolicy(device) > CONNECTION_POLICY_FORBIDDEN) { @@ -1944,10 +1945,10 @@ public class AdapterService extends Service { /** Initializes all the profile services fields */ private void initProfileServices() { Log.i(TAG, "initProfileServices: Initializing all bluetooth profile services"); - mA2dpService = A2dpService.getA2dpService(); - mA2dpSinkService = A2dpSinkService.getA2dpSinkService(); mHeadsetService = HeadsetService.getHeadsetService(); mHeadsetClientService = HeadsetClientService.getHeadsetClientService(); + mA2dpService = A2dpService.getA2dpService(); + mA2dpSinkService = A2dpSinkService.getA2dpSinkService(); mMapService = BluetoothMapService.getBluetoothMapService(); mMapClientService = MapClientService.getMapClientService(); mHidDeviceService = HidDeviceService.getHidDeviceService(); @@ -2754,6 +2755,15 @@ public class AdapterService extends Service { return new BluetoothAddress(identityAddress, identityAddressType); } + public boolean addAssociatedPackage(BluetoothDevice device, String packageName) { + DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); + if (deviceProp == null) { + return false; + } + deviceProp.addPackage(packageName); + return true; + } + private record CallerInfo(String callerPackageName, UserHandle user) {} boolean createBond( @@ -3203,35 +3213,32 @@ public class AdapterService extends Service { Log.e(TAG, "setActiveDevice: Bluetooth is not enabled"); return false; } - boolean setA2dp = false; boolean setHeadset = false; + boolean setA2dp = false; // Determine for which profiles we want to set device as our active device switch (profiles) { - case BluetoothAdapter.ACTIVE_DEVICE_AUDIO: - setA2dp = true; - break; - case BluetoothAdapter.ACTIVE_DEVICE_PHONE_CALL: + case BluetoothAdapter.ACTIVE_DEVICE_PHONE_CALL -> setHeadset = true; + case BluetoothAdapter.ACTIVE_DEVICE_AUDIO -> setA2dp = true; + case BluetoothAdapter.ACTIVE_DEVICE_ALL -> { setHeadset = true; - break; - case BluetoothAdapter.ACTIVE_DEVICE_ALL: setA2dp = true; - setHeadset = true; - break; - default: + } + default -> { return false; + } } - boolean a2dpSupported = - mA2dpService != null - && (device == null - || mA2dpService.getConnectionPolicy(device) - == CONNECTION_POLICY_ALLOWED); boolean hfpSupported = mHeadsetService != null && (device == null || mHeadsetService.getConnectionPolicy(device) == CONNECTION_POLICY_ALLOWED); + boolean a2dpSupported = + mA2dpService != null + && (device == null + || mA2dpService.getConnectionPolicy(device) + == CONNECTION_POLICY_ALLOWED); boolean leAudioSupported = mLeAudioService != null && (device == null @@ -3254,6 +3261,12 @@ public class AdapterService extends Service { } } + // Order matters, some devices do not accept A2DP connection before HFP connection + if (setHeadset && hfpSupported) { + Log.i(TAG, "setActiveDevice: Setting active Headset " + device); + mHeadsetService.setActiveDevice(device); + } + if (setA2dp && a2dpSupported) { Log.i(TAG, "setActiveDevice: Setting active A2dp device " + device); if (device == null) { @@ -3285,11 +3298,6 @@ public class AdapterService extends Service { } } - if (setHeadset && hfpSupported) { - Log.i(TAG, "setActiveDevice: Setting active Headset " + device); - mHeadsetService.setActiveDevice(device); - } - return true; } @@ -3304,8 +3312,8 @@ public class AdapterService extends Service { if (mLeAudioService == null) { return false; } - boolean a2dpSupported = isProfileSupported(leAudioDevice, BluetoothProfile.A2DP); boolean hfpSupported = isProfileSupported(leAudioDevice, BluetoothProfile.HEADSET); + boolean a2dpSupported = isProfileSupported(leAudioDevice, BluetoothProfile.A2DP); List<BluetoothDevice> groupDevices = mLeAudioService.getGroupDevices(leAudioDevice); if (hfpSupported && mHeadsetService != null) { @@ -3411,26 +3419,11 @@ public class AdapterService extends Service { return BluetoothStatusCodes.SUCCESS; } - /** - * Connect all supported bluetooth profiles between the local and remote device - * - * @param device is the remote device with which to connect all supported profiles - */ + /** All profile toggles are disabled, so connects all supported profiles */ void connectAllSupportedProfiles(BluetoothDevice device) { int numProfilesConnected = 0; - // All profile toggles disabled, so connects all supported profiles - if (mA2dpService != null && isProfileSupported(device, BluetoothProfile.A2DP)) { - Log.i(TAG, "connectAllSupportedProfiles: Connecting A2dp"); - // Set connection policy also connects the profile with CONNECTION_POLICY_ALLOWED - mA2dpService.setConnectionPolicy(device, CONNECTION_POLICY_ALLOWED); - numProfilesConnected++; - } - if (mA2dpSinkService != null && isProfileSupported(device, BluetoothProfile.A2DP_SINK)) { - Log.i(TAG, "connectAllSupportedProfiles: Connecting A2dp Sink"); - mA2dpSinkService.setConnectionPolicy(device, CONNECTION_POLICY_ALLOWED); - numProfilesConnected++; - } + // Order matters, some devices do not accept A2DP connection before HFP connection if (mHeadsetService != null && isProfileSupported(device, BluetoothProfile.HEADSET)) { Log.i(TAG, "connectAllSupportedProfiles: Connecting Headset Profile"); mHeadsetService.setConnectionPolicy(device, CONNECTION_POLICY_ALLOWED); @@ -3442,6 +3435,17 @@ public class AdapterService extends Service { mHeadsetClientService.setConnectionPolicy(device, CONNECTION_POLICY_ALLOWED); numProfilesConnected++; } + if (mA2dpService != null && isProfileSupported(device, BluetoothProfile.A2DP)) { + Log.i(TAG, "connectAllSupportedProfiles: Connecting A2dp"); + // Set connection policy also connects the profile with CONNECTION_POLICY_ALLOWED + mA2dpService.setConnectionPolicy(device, CONNECTION_POLICY_ALLOWED); + numProfilesConnected++; + } + if (mA2dpSinkService != null && isProfileSupported(device, BluetoothProfile.A2DP_SINK)) { + Log.i(TAG, "connectAllSupportedProfiles: Connecting A2dp Sink"); + mA2dpSinkService.setConnectionPolicy(device, CONNECTION_POLICY_ALLOWED); + numProfilesConnected++; + } if (mMapClientService != null && isProfileSupported(device, BluetoothProfile.MAP_CLIENT)) { Log.i(TAG, "connectAllSupportedProfiles: Connecting MAP"); mMapClientService.setConnectionPolicy(device, CONNECTION_POLICY_ALLOWED); @@ -3530,18 +3534,6 @@ public class AdapterService extends Service { return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED; } - if (mA2dpService != null - && (mA2dpService.getConnectionState(device) == STATE_CONNECTED - || mA2dpService.getConnectionState(device) == STATE_CONNECTING)) { - Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting A2dp"); - mA2dpService.disconnect(device); - } - if (mA2dpSinkService != null - && (mA2dpSinkService.getConnectionState(device) == STATE_CONNECTED - || mA2dpSinkService.getConnectionState(device) == STATE_CONNECTING)) { - Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting A2dp Sink"); - mA2dpSinkService.disconnect(device); - } if (mHeadsetService != null && (mHeadsetService.getConnectionState(device) == STATE_CONNECTED || mHeadsetService.getConnectionState(device) == STATE_CONNECTING)) { @@ -3554,6 +3546,18 @@ public class AdapterService extends Service { Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting HFP"); mHeadsetClientService.disconnect(device); } + if (mA2dpService != null + && (mA2dpService.getConnectionState(device) == STATE_CONNECTED + || mA2dpService.getConnectionState(device) == STATE_CONNECTING)) { + Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting A2dp"); + mA2dpService.disconnect(device); + } + if (mA2dpSinkService != null + && (mA2dpSinkService.getConnectionState(device) == STATE_CONNECTED + || mA2dpSinkService.getConnectionState(device) == STATE_CONNECTING)) { + Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting A2dp Sink"); + mA2dpSinkService.disconnect(device); + } if (mMapClientService != null && (mMapClientService.getConnectionState(device) == STATE_CONNECTED || mMapClientService.getConnectionState(device) == STATE_CONNECTING)) { @@ -4206,12 +4210,12 @@ public class AdapterService extends Service { /** Handle Bluetooth profiles when bond state changes with a {@link BluetoothDevice} */ public void handleBondStateChanged(BluetoothDevice device, int fromState, int toState) { - if (mA2dpService != null && mA2dpService.isAvailable()) { - mA2dpService.handleBondStateChanged(device, fromState, toState); - } if (mHeadsetService != null && mHeadsetService.isAvailable()) { mHeadsetService.handleBondStateChanged(device, fromState, toState); } + if (mA2dpService != null && mA2dpService.isAvailable()) { + mA2dpService.handleBondStateChanged(device, fromState, toState); + } if (mLeAudioService != null && mLeAudioService.isAvailable()) { mLeAudioService.handleBondStateChanged(device, fromState, toState); } diff --git a/android/app/src/com/android/bluetooth/btservice/AdapterServiceBinder.java b/android/app/src/com/android/bluetooth/btservice/AdapterServiceBinder.java index 57776bc560..aff6642b7d 100644 --- a/android/app/src/com/android/bluetooth/btservice/AdapterServiceBinder.java +++ b/android/app/src/com/android/bluetooth/btservice/AdapterServiceBinder.java @@ -27,7 +27,10 @@ import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED; import static com.android.bluetooth.ChangeIds.ENFORCE_CONNECT; import static com.android.bluetooth.Utils.callerIsSystem; import static com.android.bluetooth.Utils.callerIsSystemOrActiveOrManagedUser; +import static com.android.bluetooth.Utils.checkConnectPermissionForDataDelivery; +import static com.android.bluetooth.Utils.checkScanPermissionForDataDelivery; import static com.android.bluetooth.Utils.getBytesFromAddress; +import static com.android.bluetooth.Utils.getUidPidString; import static java.util.Objects.requireNonNull; @@ -162,7 +165,6 @@ class AdapterServiceBinder extends IBluetooth.Stub { } service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); - service.offToBleOn(quietMode); } @@ -174,7 +176,6 @@ class AdapterServiceBinder extends IBluetooth.Stub { } service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); - service.onToBleOn(); } @@ -183,13 +184,11 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getAddress") - || !Utils.checkConnectPermissionForDataDelivery( - service, source, "AdapterService getAddress")) { + || !checkConnectPermissionForDataDelivery(service, source, TAG, "getAddress")) { return null; } service.enforceCallingOrSelfPermission(LOCAL_MAC_ADDRESS, null); - return Utils.getAddressStringFromByte(service.getAdapterProperties().getAddress()); } @@ -198,8 +197,7 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getUuids") - || !Utils.checkConnectPermissionForDataDelivery( - service, source, "AdapterService getUuids")) { + || !checkConnectPermissionForDataDelivery(service, source, TAG, "getUuids")) { return Collections.emptyList(); } @@ -215,12 +213,14 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getIdentityAddress") - || !Utils.checkConnectPermissionForDataDelivery( + || !checkConnectPermissionForDataDelivery( service, Utils.getCallingAttributionSource(mService), - "AdapterService getIdentityAddress")) { + TAG, + "getIdentityAddress")) { return null; } + service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); return service.getIdentityAddress(address); } @@ -231,12 +231,14 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getIdentityAddressWithType") - || !Utils.checkConnectPermissionForDataDelivery( + || !checkConnectPermissionForDataDelivery( service, Utils.getCallingAttributionSource(mService), - "AdapterService getIdentityAddressWithType")) { + TAG, + "getIdentityAddressWithType")) { return new BluetoothAddress(null, BluetoothDevice.ADDRESS_TYPE_UNKNOWN); } + service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); return service.getIdentityAddressWithType(address); } @@ -246,8 +248,7 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getName") - || !Utils.checkConnectPermissionForDataDelivery( - service, source, "AdapterService getName")) { + || !checkConnectPermissionForDataDelivery(service, source, TAG, "getName")) { return null; } @@ -271,8 +272,7 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "setName") - || !Utils.checkConnectPermissionForDataDelivery( - service, source, "AdapterService setName")) { + || !checkConnectPermissionForDataDelivery(service, source, TAG, "setName")) { return false; } @@ -293,8 +293,7 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getScanMode") - || !Utils.checkScanPermissionForDataDelivery( - service, source, "AdapterService getScanMode")) { + || !checkScanPermissionForDataDelivery(service, source, TAG, "getScanMode")) { return SCAN_MODE_NONE; } @@ -306,13 +305,12 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "setScanMode") - || !Utils.checkScanPermissionForDataDelivery( - service, source, "AdapterService setScanMode")) { + || !checkScanPermissionForDataDelivery(service, source, TAG, "setScanMode")) { return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_SCAN_PERMISSION; } service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); - String logCaller = Utils.getUidPidString() + " packageName=" + source.getPackageName(); + String logCaller = getUidPidString() + " packageName=" + source.getPackageName(); CompletableFuture<Boolean> future = new CompletableFuture<>(); mService.getHandler() .post( @@ -328,8 +326,8 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getDiscoverableTimeout") - || !Utils.checkScanPermissionForDataDelivery( - service, source, "AdapterService getDiscoverableTimeout")) { + || !checkScanPermissionForDataDelivery( + service, source, TAG, "getDiscoverableTimeout")) { return -1; } @@ -341,12 +339,12 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "setDiscoverableTimeout") - || !Utils.checkScanPermissionForDataDelivery( - service, source, "AdapterService setDiscoverableTimeout")) { + || !checkScanPermissionForDataDelivery( + service, source, TAG, "setDiscoverableTimeout")) { return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_SCAN_PERMISSION; } - service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); + service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); return service.getAdapterProperties().setDiscoverableTimeout((int) timeout) ? BluetoothStatusCodes.SUCCESS : BluetoothStatusCodes.ERROR_UNKNOWN; @@ -356,15 +354,12 @@ class AdapterServiceBinder extends IBluetooth.Stub { public boolean startDiscovery(AttributionSource source) { AdapterService service = getService(); if (service == null - || !callerIsSystemOrActiveOrManagedUser(service, TAG, "startDiscovery")) { - return false; - } - - if (!Utils.checkScanPermissionForDataDelivery(service, source, "Starting discovery.")) { + || !callerIsSystemOrActiveOrManagedUser(service, TAG, "startDiscovery") + || !checkScanPermissionForDataDelivery(service, source, TAG, "startDiscovery")) { return false; } - Log.i(TAG, "startDiscovery: from " + Utils.getUidPidString()); + Log.i(TAG, "startDiscovery: from " + getUidPidString()); return service.startDiscovery(source); } @@ -373,12 +368,11 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "cancelDiscovery") - || !Utils.checkScanPermissionForDataDelivery( - service, source, "AdapterService cancelDiscovery")) { + || !checkScanPermissionForDataDelivery(service, source, TAG, "cancelDiscovery")) { return false; } - Log.i(TAG, "cancelDiscovery: from " + Utils.getUidPidString()); + Log.i(TAG, "cancelDiscovery: from " + getUidPidString()); return service.getNative().cancelDiscovery(); } @@ -387,8 +381,7 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "isDiscovering") - || !Utils.checkScanPermissionForDataDelivery( - service, source, "AdapterService isDiscovering")) { + || !checkScanPermissionForDataDelivery(service, source, TAG, "isDiscovering")) { return false; } @@ -400,7 +393,8 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getDiscoveryEndMillis") - || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + || !checkConnectPermissionForDataDelivery( + service, source, TAG, "getDiscoveryEndMillis")) { return -1; } @@ -414,8 +408,8 @@ class AdapterServiceBinder extends IBluetooth.Stub { // don't check caller, may be called from system UI AdapterService service = getService(); if (service == null - || !Utils.checkConnectPermissionForDataDelivery( - service, source, "AdapterService getMostRecentlyConnectedDevices")) { + || !checkConnectPermissionForDataDelivery( + service, source, TAG, "getMostRecentlyConnectedDevices")) { return Collections.emptyList(); } @@ -429,8 +423,8 @@ class AdapterServiceBinder extends IBluetooth.Stub { // don't check caller, may be called from system UI AdapterService service = getService(); if (service == null - || !Utils.checkConnectPermissionForDataDelivery( - service, source, "AdapterService getBondedDevices")) { + || !checkConnectPermissionForDataDelivery( + service, source, TAG, "getBondedDevices")) { return Collections.emptyList(); } @@ -466,8 +460,8 @@ class AdapterServiceBinder extends IBluetooth.Stub { if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getProfileConnectionState") || (checkConnect - && !Utils.checkConnectPermissionForDataDelivery( - service, source, "AdapterService getProfileConnectionState"))) { + && !checkConnectPermissionForDataDelivery( + service, source, TAG, "getProfileConnectionState"))) { return STATE_DISCONNECTED; } @@ -479,8 +473,7 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "createBond") - || !Utils.checkConnectPermissionForDataDelivery( - service, source, "AdapterService createBond")) { + || !checkConnectPermissionForDataDelivery(service, source, TAG, "createBond")) { return false; } @@ -489,7 +482,7 @@ class AdapterServiceBinder extends IBluetooth.Stub { "createBond:" + (" device=" + device) + (" transport=" + transport) - + (" from " + Utils.getUidPidString())); + + (" from " + getUidPidString())); return service.createBond(device, transport, null, null, source.getPackageName()); } @@ -502,9 +495,9 @@ class AdapterServiceBinder extends IBluetooth.Stub { AttributionSource source) { AdapterService service = getService(); if (service == null - || !callerIsSystemOrActiveOrManagedUser(service, TAG, "createBond") - || !Utils.checkConnectPermissionForDataDelivery( - service, source, "AdapterService createBond")) { + || !callerIsSystemOrActiveOrManagedUser(service, TAG, "createBondOutOfBand") + || !checkConnectPermissionForDataDelivery( + service, source, TAG, "createBondOutOfBand")) { return false; } @@ -515,7 +508,7 @@ class AdapterServiceBinder extends IBluetooth.Stub { "createBondOutOfBand:" + (" device=" + device) + (" transport=" + transport) - + (" from " + Utils.getUidPidString())); + + (" from " + getUidPidString())); return service.createBond( device, transport, remoteP192Data, remoteP256Data, source.getPackageName()); } @@ -525,14 +518,14 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "cancelBondProcess") - || !Utils.checkConnectPermissionForDataDelivery( - service, source, "AdapterService cancelBondProcess")) { + || !checkConnectPermissionForDataDelivery( + service, source, TAG, "cancelBondProcess")) { return false; } service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); - Log.i(TAG, "cancelBondProcess: device=" + device + ", from " + Utils.getUidPidString()); + Log.i(TAG, "cancelBondProcess: device=" + device + ", from " + getUidPidString()); DeviceProperties deviceProp = service.getRemoteDevices().getDeviceProperties(device); if (deviceProp != null) { @@ -548,12 +541,11 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "removeBond") - || !Utils.checkConnectPermissionForDataDelivery( - service, source, "AdapterService removeBond")) { + || !checkConnectPermissionForDataDelivery(service, source, TAG, "removeBond")) { return false; } - Log.i(TAG, "removeBond: device=" + device + ", from " + Utils.getUidPidString()); + Log.i(TAG, "removeBond: device=" + device + ", from " + getUidPidString()); DeviceProperties deviceProp = service.getRemoteDevices().getDeviceProperties(device); if (deviceProp == null || deviceProp.getBondState() != BluetoothDevice.BOND_BONDED) { @@ -582,8 +574,7 @@ class AdapterServiceBinder extends IBluetooth.Stub { // don't check caller, may be called from system UI AdapterService service = getService(); if (service == null - || !Utils.checkConnectPermissionForDataDelivery( - service, source, "AdapterService getBondState")) { + || !checkConnectPermissionForDataDelivery(service, source, TAG, "getBondState")) { return BluetoothDevice.BOND_NONE; } @@ -595,8 +586,8 @@ class AdapterServiceBinder extends IBluetooth.Stub { // don't check caller, may be called from system UI AdapterService service = getService(); if (service == null - || !Utils.checkConnectPermissionForDataDelivery( - service, source, "AdapterService isBondingInitiatedLocally")) { + || !checkConnectPermissionForDataDelivery( + service, source, TAG, "isBondingInitiatedLocally")) { return false; } @@ -610,7 +601,8 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "generateLocalOobData") - || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + || !checkConnectPermissionForDataDelivery( + service, source, TAG, "generateLocalOobData")) { return; } service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); @@ -620,11 +612,13 @@ class AdapterServiceBinder extends IBluetooth.Stub { @Override public long getSupportedProfiles(AttributionSource source) { AdapterService service = getService(); - if (service == null || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + if (service == null + || !checkConnectPermissionForDataDelivery( + service, source, TAG, "getSupportedProfiles")) { return 0; } - service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); + service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); return Config.getSupportedProfilesBitMask(); } @@ -632,8 +626,8 @@ class AdapterServiceBinder extends IBluetooth.Stub { public int getConnectionState(BluetoothDevice device, AttributionSource source) { AdapterService service = getService(); if (service == null - || !Utils.checkConnectPermissionForDataDelivery( - service, source, "AdapterService getConnectionState")) { + || !checkConnectPermissionForDataDelivery( + service, source, TAG, "getConnectionState")) { return BluetoothDevice.CONNECTION_STATE_DISCONNECTED; } @@ -646,24 +640,25 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getConnectionHandle") - || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + || !checkConnectPermissionForDataDelivery( + service, source, TAG, "getConnectionHandle")) { return BluetoothDevice.ERROR; } service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); - return service.getConnectionHandle(device, transport); } @Override public boolean canBondWithoutDialog(BluetoothDevice device, AttributionSource source) { AdapterService service = getService(); - if (service == null || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + if (service == null + || !checkConnectPermissionForDataDelivery( + service, source, TAG, "canBondWithoutDialog")) { return false; } service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); - return service.canBondWithoutDialog(device); } @@ -672,12 +667,13 @@ class AdapterServiceBinder extends IBluetooth.Stub { BluetoothDevice device, AttributionSource source) { AdapterService service = getService(); - if (service == null || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + if (service == null + || !checkConnectPermissionForDataDelivery( + service, source, TAG, "getPackageNameOfBondingApplication")) { return null; } service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); - return service.getPackageNameOfBondingApplication(device); } @@ -686,16 +682,15 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "removeActiveDevice") - || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + || !checkConnectPermissionForDataDelivery( + service, source, TAG, "removeActiveDevice")) { return false; } service.enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null); service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); - Log.i( - TAG, - "removeActiveDevice: profiles=" + profiles + ", from " + Utils.getUidPidString()); + Log.i(TAG, "removeActiveDevice: profiles=" + profiles + ", from " + getUidPidString()); return service.setActiveDevice(null, profiles); } @@ -705,7 +700,8 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "setActiveDevice") - || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + || !checkConnectPermissionForDataDelivery( + service, source, TAG, "setActiveDevice")) { return false; } @@ -719,7 +715,7 @@ class AdapterServiceBinder extends IBluetooth.Stub { + ", profiles=" + profiles + ", from " - + Utils.getUidPidString()); + + getUidPidString()); return service.setActiveDevice(device, profiles); } @@ -730,12 +726,12 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getActiveDevices") - || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + || !checkConnectPermissionForDataDelivery( + service, source, TAG, "getActiveDevices")) { return Collections.emptyList(); } service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); - return service.getActiveDevices(profile); } @@ -754,19 +750,15 @@ class AdapterServiceBinder extends IBluetooth.Stub { if (!BluetoothAdapter.checkBluetoothAddress(device.getAddress())) { throw new IllegalArgumentException("device cannot have an invalid address"); } - if (!Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + if (!checkConnectPermissionForDataDelivery( + service, source, TAG, "connectAllEnabledProfiles")) { return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION; } service.enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null); service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); - Log.i( - TAG, - "connectAllEnabledProfiles: device=" - + device - + ", from " - + Utils.getUidPidString()); + Log.i(TAG, "connectAllEnabledProfiles: device=" + device + ", from " + getUidPidString()); MetricsLogger.getInstance() .logBluetoothEvent( device, @@ -799,7 +791,8 @@ class AdapterServiceBinder extends IBluetooth.Stub { if (!BluetoothAdapter.checkBluetoothAddress(device.getAddress())) { throw new IllegalArgumentException("device cannot have an invalid address"); } - if (!Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + if (!checkConnectPermissionForDataDelivery( + service, source, TAG, "disconnectAllEnabledProfiles")) { return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION; } @@ -807,10 +800,7 @@ class AdapterServiceBinder extends IBluetooth.Stub { Log.i( TAG, - "disconnectAllEnabledProfiles: device=" - + device - + ", from " - + Utils.getUidPidString()); + "disconnectAllEnabledProfiles: device=" + device + ", from " + getUidPidString()); try { return service.disconnectAllEnabledProfiles(device); @@ -826,8 +816,7 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getRemoteName") - || !Utils.checkConnectPermissionForDataDelivery( - service, source, "AdapterService getRemoteName")) { + || !checkConnectPermissionForDataDelivery(service, source, TAG, "getRemoteName")) { return null; } @@ -839,8 +828,7 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getRemoteType") - || !Utils.checkConnectPermissionForDataDelivery( - service, source, "AdapterService getRemoteType")) { + || !checkConnectPermissionForDataDelivery(service, source, TAG, "getRemoteType")) { return BluetoothDevice.DEVICE_TYPE_UNKNOWN; } @@ -852,8 +840,7 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getRemoteAlias") - || !Utils.checkConnectPermissionForDataDelivery( - service, source, "AdapterService getRemoteAlias")) { + || !checkConnectPermissionForDataDelivery(service, source, TAG, "getRemoteAlias")) { return null; } @@ -874,8 +861,7 @@ class AdapterServiceBinder extends IBluetooth.Stub { throw new IllegalArgumentException("alias cannot be the empty string"); } - if (!Utils.checkConnectPermissionForDataDelivery( - service, source, "AdapterService setRemoteAlias")) { + if (!checkConnectPermissionForDataDelivery(service, source, TAG, "setRemoteAlias")) { return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION; } @@ -895,8 +881,7 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getRemoteClass") - || !Utils.checkConnectPermissionForDataDelivery( - service, source, "AdapterService getRemoteClass")) { + || !checkConnectPermissionForDataDelivery(service, source, TAG, "getRemoteClass")) { return 0; } @@ -908,8 +893,7 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getRemoteUuids") - || !Utils.checkConnectPermissionForDataDelivery( - service, source, "AdapterService getRemoteUuids")) { + || !checkConnectPermissionForDataDelivery(service, source, TAG, "getRemoteUuids")) { return Collections.emptyList(); } @@ -926,8 +910,8 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "fetchRemoteUuids") - || !Utils.checkConnectPermissionForDataDelivery( - service, source, "AdapterService fetchRemoteUuids")) { + || !checkConnectPermissionForDataDelivery( + service, source, TAG, "fetchRemoteUuids")) { return false; } if (transport != TRANSPORT_AUTO) { @@ -941,7 +925,7 @@ class AdapterServiceBinder extends IBluetooth.Stub { + ", transport=" + transport + ", from " - + Utils.getUidPidString()); + + getUidPidString()); service.getRemoteDevices().fetchUuids(device, transport); MetricsLogger.getInstance().cacheCount(BluetoothProtoEnums.SDP_FETCH_UUID_REQUEST, 1); @@ -958,8 +942,7 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "setPin") - || !Utils.checkConnectPermissionForDataDelivery( - service, source, "AdapterService setPin")) { + || !checkConnectPermissionForDataDelivery(service, source, TAG, "setPin")) { return false; } @@ -978,12 +961,7 @@ class AdapterServiceBinder extends IBluetooth.Stub { service.logUserBondResponse(device, accept, source); Log.i( TAG, - "setPin: device=" - + device - + ", accept=" - + accept - + ", from " - + Utils.getUidPidString()); + "setPin: device=" + device + ", accept=" + accept + ", from " + getUidPidString()); return service.getNative() .pinReply(getBytesFromAddress(device.getAddress()), accept, len, pinCode); } @@ -998,8 +976,7 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "setPasskey") - || !Utils.checkConnectPermissionForDataDelivery( - service, source, "AdapterService setPasskey")) { + || !checkConnectPermissionForDataDelivery(service, source, TAG, "setPasskey")) { return false; } @@ -1021,7 +998,7 @@ class AdapterServiceBinder extends IBluetooth.Stub { + ", accept=" + accept + ", from " - + Utils.getUidPidString()); + + getUidPidString()); return service.getNative() .sspReply( @@ -1037,7 +1014,8 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "setPairingConfirmation") - || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + || !checkConnectPermissionForDataDelivery( + service, source, TAG, "setPairingConfirmation")) { return false; } @@ -1056,7 +1034,7 @@ class AdapterServiceBinder extends IBluetooth.Stub { + ", accept=" + accept + ", from " - + Utils.getUidPidString()); + + getUidPidString()); return service.getNative() .sspReply( @@ -1071,12 +1049,11 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getSilenceMode") - || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + || !checkConnectPermissionForDataDelivery(service, source, TAG, "getSilenceMode")) { return false; } service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); - return service.getSilenceDeviceManager().getSilenceMode(device); } @@ -1086,12 +1063,11 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "setSilenceMode") - || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + || !checkConnectPermissionForDataDelivery(service, source, TAG, "setSilenceMode")) { return false; } service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); - service.getSilenceDeviceManager().setSilenceMode(device, silence); return true; } @@ -1102,8 +1078,8 @@ class AdapterServiceBinder extends IBluetooth.Stub { if (service == null || !callerIsSystemOrActiveOrManagedUser( service, TAG, "getPhonebookAccessPermission") - || !Utils.checkConnectPermissionForDataDelivery( - service, source, "AdapterService getPhonebookAccessPermission")) { + || !checkConnectPermissionForDataDelivery( + service, source, TAG, "getPhonebookAccessPermission")) { return BluetoothDevice.ACCESS_UNKNOWN; } @@ -1117,12 +1093,12 @@ class AdapterServiceBinder extends IBluetooth.Stub { if (service == null || !callerIsSystemOrActiveOrManagedUser( service, TAG, "setPhonebookAccessPermission") - || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + || !checkConnectPermissionForDataDelivery( + service, source, TAG, "setPhonebookAccessPermission")) { return false; } service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); - service.setPhonebookAccessPermission(device, value); return true; } @@ -1132,8 +1108,8 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getMessageAccessPermission") - || !Utils.checkConnectPermissionForDataDelivery( - service, source, "AdapterService getMessageAccessPermission")) { + || !checkConnectPermissionForDataDelivery( + service, source, TAG, "getMessageAccessPermission")) { return BluetoothDevice.ACCESS_UNKNOWN; } @@ -1146,12 +1122,12 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "setMessageAccessPermission") - || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + || !checkConnectPermissionForDataDelivery( + service, source, TAG, "setMessageAccessPermission")) { return false; } service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); - service.setMessageAccessPermission(device, value); return true; } @@ -1161,8 +1137,8 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getSimAccessPermission") - || !Utils.checkConnectPermissionForDataDelivery( - service, source, "AdapterService getSimAccessPermission")) { + || !checkConnectPermissionForDataDelivery( + service, source, TAG, "getSimAccessPermission")) { return BluetoothDevice.ACCESS_UNKNOWN; } @@ -1175,12 +1151,12 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "setSimAccessPermission") - || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + || !checkConnectPermissionForDataDelivery( + service, source, TAG, "setSimAccessPermission")) { return false; } service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); - service.setSimAccessPermission(device, value); return true; } @@ -1270,8 +1246,7 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "sdpSearch") - || !Utils.checkConnectPermissionForDataDelivery( - service, source, "AdapterService sdpSearch")) { + || !checkConnectPermissionForDataDelivery(service, source, TAG, "sdpSearch")) { return false; } return service.sdpSearch(device, uuid); @@ -1282,8 +1257,8 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getBatteryLevel") - || !Utils.checkConnectPermissionForDataDelivery( - service, source, "AdapterService getBatteryLevel")) { + || !checkConnectPermissionForDataDelivery( + service, source, TAG, "getBatteryLevel")) { return BluetoothDevice.BATTERY_LEVEL_UNKNOWN; } @@ -1299,8 +1274,8 @@ class AdapterServiceBinder extends IBluetooth.Stub { // don't check caller, may be called from system UI AdapterService service = getService(); if (service == null - || !Utils.checkConnectPermissionForDataDelivery( - service, source, "AdapterService getMaxConnectedAudioDevices")) { + || !checkConnectPermissionForDataDelivery( + service, source, TAG, "getMaxConnectedAudioDevices")) { return -1; } @@ -1310,7 +1285,8 @@ class AdapterServiceBinder extends IBluetooth.Stub { @Override public boolean factoryReset(AttributionSource source) { AdapterService service = getService(); - if (service == null || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + if (service == null + || !checkConnectPermissionForDataDelivery(service, source, TAG, "factoryReset")) { return false; } @@ -1325,7 +1301,8 @@ class AdapterServiceBinder extends IBluetooth.Stub { if (service == null || !callerIsSystemOrActiveOrManagedUser( service, TAG, "registerBluetoothConnectionCallback") - || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + || !checkConnectPermissionForDataDelivery( + service, source, TAG, "registerBluetoothConnectionCallback")) { return; } service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); @@ -1339,7 +1316,8 @@ class AdapterServiceBinder extends IBluetooth.Stub { if (service == null || !callerIsSystemOrActiveOrManagedUser( service, TAG, "unregisterBluetoothConnectionCallback") - || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + || !checkConnectPermissionForDataDelivery( + service, source, TAG, "unregisterBluetoothConnectionCallback")) { return; } service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); @@ -1351,12 +1329,12 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "registerCallback") - || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + || !checkConnectPermissionForDataDelivery( + service, source, TAG, "registerCallback")) { return; } service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); - service.registerRemoteCallback(callback); } @@ -1365,12 +1343,12 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "unregisterCallback") - || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + || !checkConnectPermissionForDataDelivery( + service, source, TAG, "unregisterCallback")) { return; } service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); - service.unregisterRemoteCallback(callback); } @@ -1510,7 +1488,8 @@ class AdapterServiceBinder extends IBluetooth.Stub { } else if (!callerIsSystemOrActiveOrManagedUser( service, TAG, "isDistanceMeasurementSupported")) { return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED; - } else if (!Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + } else if (!checkConnectPermissionForDataDelivery( + service, source, TAG, "isDistanceMeasurementSupported")) { return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION; } service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); @@ -1540,12 +1519,13 @@ class AdapterServiceBinder extends IBluetooth.Stub { @Override public BluetoothActivityEnergyInfo reportActivityInfo(AttributionSource source) { AdapterService service = getService(); - if (service == null || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + if (service == null + || !checkConnectPermissionForDataDelivery( + service, source, TAG, "reportActivityInfo")) { return null; } service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); - return service.reportActivityInfo(); } @@ -1557,19 +1537,18 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "registerMetadataListener") - || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + || !checkConnectPermissionForDataDelivery( + service, source, TAG, "registerMetadataListener")) { return false; } service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); - service.getHandler() .post( () -> service.getMetadataListeners() .computeIfAbsent(device, k -> new RemoteCallbackList()) .register(listener)); - return true; } @@ -1581,12 +1560,12 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "unregisterMetadataListener") - || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + || !checkConnectPermissionForDataDelivery( + service, source, TAG, "unregisterMetadataListener")) { return false; } service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); - service.getHandler() .post( () -> @@ -1609,7 +1588,7 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "setMetadata") - || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + || !checkConnectPermissionForDataDelivery(service, source, TAG, "setMetadata")) { return false; } @@ -1622,12 +1601,11 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getMetadata") - || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + || !checkConnectPermissionForDataDelivery(service, source, TAG, "getMetadata")) { return null; } service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); - return service.getMetadata(device, key); } @@ -1638,9 +1616,11 @@ class AdapterServiceBinder extends IBluetooth.Stub { if (service == null || !callerIsSystemOrActiveOrManagedUser( service, TAG, "isRequestAudioPolicyAsSinkSupported") - || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + || !checkConnectPermissionForDataDelivery( + service, source, TAG, "isRequestAudioPolicyAsSinkSupported")) { return BluetoothStatusCodes.FEATURE_NOT_CONFIGURED; } + service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); return service.isRequestAudioPolicyAsSinkSupported(device); } @@ -1653,9 +1633,11 @@ class AdapterServiceBinder extends IBluetooth.Stub { return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED; } else if (!callerIsSystemOrActiveOrManagedUser(service, TAG, "requestAudioPolicyAsSink")) { return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED; - } else if (!Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + } else if (!checkConnectPermissionForDataDelivery( + service, source, TAG, "requestAudioPolicyAsSink")) { return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION; } + service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); return service.requestAudioPolicyAsSink(device, policies); } @@ -1667,9 +1649,11 @@ class AdapterServiceBinder extends IBluetooth.Stub { if (service == null || !callerIsSystemOrActiveOrManagedUser( service, TAG, "getRequestedAudioPolicyAsSink") - || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + || !checkConnectPermissionForDataDelivery( + service, source, TAG, "getRequestedAudioPolicyAsSink")) { return null; } + service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); return service.getRequestedAudioPolicyAsSink(device); } @@ -1693,7 +1677,6 @@ class AdapterServiceBinder extends IBluetooth.Stub { } service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); - service.bleOnToOn(); } @@ -1705,7 +1688,6 @@ class AdapterServiceBinder extends IBluetooth.Stub { } service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); - service.bleOnToOff(); } @@ -1718,7 +1700,6 @@ class AdapterServiceBinder extends IBluetooth.Stub { } service.enforceCallingOrSelfPermission(DUMP, null); - service.dump(fd, writer, args); writer.close(); } @@ -1728,12 +1709,14 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "allowLowLatencyAudio") - || !Utils.checkConnectPermissionForDataDelivery( + || !checkConnectPermissionForDataDelivery( service, Utils.getCallingAttributionSource(service), - "AdapterService allowLowLatencyAudio")) { + TAG, + "allowLowLatencyAudio")) { return false; } + service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); return service.allowLowLatencyAudio(allowed, device); } @@ -1744,10 +1727,11 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "startRfcommListener") - || !Utils.checkConnectPermissionForDataDelivery( - service, source, "AdapterService startRfcommListener")) { + || !checkConnectPermissionForDataDelivery( + service, source, TAG, "startRfcommListener")) { return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED; } + service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); return service.startRfcommListener(name, uuid, pendingIntent, source); } @@ -1757,10 +1741,11 @@ class AdapterServiceBinder extends IBluetooth.Stub { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "stopRfcommListener") - || !Utils.checkConnectPermissionForDataDelivery( - service, source, "AdapterService stopRfcommListener")) { + || !checkConnectPermissionForDataDelivery( + service, source, TAG, "stopRfcommListener")) { return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED; } + service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); return service.stopRfcommListener(uuid, source); } @@ -1772,10 +1757,11 @@ class AdapterServiceBinder extends IBluetooth.Stub { if (service == null || !callerIsSystemOrActiveOrManagedUser( service, TAG, "retrievePendingSocketForServiceRecord") - || !Utils.checkConnectPermissionForDataDelivery( - service, source, "AdapterService retrievePendingSocketForServiceRecord")) { + || !checkConnectPermissionForDataDelivery( + service, source, TAG, "retrievePendingSocketForServiceRecord")) { return null; } + service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); return service.retrievePendingSocketForServiceRecord(uuid, source); } @@ -1784,12 +1770,14 @@ class AdapterServiceBinder extends IBluetooth.Stub { public void setForegroundUserId(int userId, AttributionSource source) { AdapterService service = getService(); if (service == null - || !Utils.checkConnectPermissionForDataDelivery( + || !checkConnectPermissionForDataDelivery( service, Utils.getCallingAttributionSource(mService), - "AdapterService setForegroundUserId")) { + TAG, + "setForegroundUserId")) { return; } + service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); Utils.setForegroundUserId(userId); } @@ -1812,11 +1800,12 @@ class AdapterServiceBinder extends IBluetooth.Stub { if (service.getBondState(device) != BluetoothDevice.BOND_BONDED) { return BluetoothStatusCodes.ERROR_DEVICE_NOT_BONDED; } - if (!Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + if (!checkConnectPermissionForDataDelivery( + service, source, TAG, "setPreferredAudioProfiles")) { return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION; } - service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); + service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); return service.setPreferredAudioProfiles(device, modeToProfileBundle); } @@ -1836,11 +1825,12 @@ class AdapterServiceBinder extends IBluetooth.Stub { if (service.getBondState(device) != BluetoothDevice.BOND_BONDED) { return Bundle.EMPTY; } - if (!Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + if (!checkConnectPermissionForDataDelivery( + service, source, TAG, "getPreferredAudioProfiles")) { return Bundle.EMPTY; } - service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); + service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); return service.getPreferredAudioProfiles(device); } @@ -1860,11 +1850,12 @@ class AdapterServiceBinder extends IBluetooth.Stub { if (service.getBondState(device) != BluetoothDevice.BOND_BONDED) { return BluetoothStatusCodes.ERROR_DEVICE_NOT_BONDED; } - if (!Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + if (!checkConnectPermissionForDataDelivery( + service, source, TAG, "notifyActiveDeviceChangeApplied")) { return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION; } - service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); + service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); return service.notifyActiveDeviceChangeApplied(device); } @@ -1874,11 +1865,12 @@ class AdapterServiceBinder extends IBluetooth.Stub { if (service == null) { return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED; } - if (!Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + if (!checkConnectPermissionForDataDelivery( + service, source, TAG, "isDualModeAudioEnabled")) { return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION; } - service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); + service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); if (!Utils.isDualModeAudioEnabled()) { return BluetoothStatusCodes.FEATURE_NOT_SUPPORTED; } @@ -1898,11 +1890,12 @@ class AdapterServiceBinder extends IBluetooth.Stub { return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED; } requireNonNull(callback); - if (!Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + if (!checkConnectPermissionForDataDelivery( + service, source, TAG, "registerPreferredAudioProfilesChangedCallback")) { return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION; } - service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); + service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); // If LE only mode is enabled, the dual mode audio feature is disabled if (!Utils.isDualModeAudioEnabled()) { return BluetoothStatusCodes.FEATURE_NOT_SUPPORTED; @@ -1924,11 +1917,12 @@ class AdapterServiceBinder extends IBluetooth.Stub { return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED; } requireNonNull(callback); - if (!Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + if (!checkConnectPermissionForDataDelivery( + service, source, TAG, "unregisterPreferredAudioProfilesChangedCallback")) { return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION; } - service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); + service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); if (!service.getPreferredAudioProfilesCallbacks().unregister(callback)) { Log.e( TAG, @@ -1951,11 +1945,12 @@ class AdapterServiceBinder extends IBluetooth.Stub { return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED; } requireNonNull(callback); - if (!Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + if (!checkConnectPermissionForDataDelivery( + service, source, TAG, "registerBluetoothQualityReportReadyCallback")) { return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION; } - service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); + service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); service.getBluetoothQualityReportReadyCallbacks().register(callback); return BluetoothStatusCodes.SUCCESS; } @@ -1972,16 +1967,16 @@ class AdapterServiceBinder extends IBluetooth.Stub { return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED; } requireNonNull(callback); - if (!Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + if (!checkConnectPermissionForDataDelivery( + service, source, TAG, "unregisterBluetoothQualityReportReadyCallback")) { return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION; } - service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); + service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); if (!service.getBluetoothQualityReportReadyCallbacks().unregister(callback)) { Log.e( TAG, - "unregisterBluetoothQualityReportReadyCallback: callback was never " - + "registered"); + "unregisterBluetoothQualityReportReadyCallback: callback was never registered"); return BluetoothStatusCodes.ERROR_CALLBACK_NOT_REGISTERED; } return BluetoothStatusCodes.SUCCESS; @@ -2021,9 +2016,9 @@ class AdapterServiceBinder extends IBluetooth.Stub { service, TAG, "unregisterHciVendorSpecificCallback")) { throw new SecurityException("not allowed"); } + service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); requireNonNull(callback); - service.getBluetoothHciVendorSpecificDispatcher().unregister(callback); } @@ -2068,12 +2063,12 @@ class AdapterServiceBinder extends IBluetooth.Stub { if (service == null || !callerIsSystemOrActiveOrManagedUser( service, TAG, "getOffloadedTransportDiscoveryDataScanSupported") - || !Utils.checkScanPermissionForDataDelivery( - service, source, "getOffloadedTransportDiscoveryDataScanSupported")) { + || !checkScanPermissionForDataDelivery( + service, source, TAG, "getOffloadedTransportDiscoveryDataScanSupported")) { return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_SCAN_PERMISSION; } - service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); + service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); return service.getOffloadedTransportDiscoveryDataScanSupported(); } @@ -2081,12 +2076,12 @@ class AdapterServiceBinder extends IBluetooth.Stub { public boolean isMediaProfileConnected(AttributionSource source) { AdapterService service = getService(); if (service == null - || !Utils.checkConnectPermissionForDataDelivery( - service, source, "AdapterService.isMediaProfileConnected")) { + || !checkConnectPermissionForDataDelivery( + service, source, TAG, "isMediaProfileConnected")) { return false; } - service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); + service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); return service.isMediaProfileConnected(); } @@ -2135,7 +2130,8 @@ class AdapterServiceBinder extends IBluetooth.Stub { if (!BluetoothAdapter.checkBluetoothAddress(device.getAddress())) { throw new IllegalArgumentException("device cannot have an invalid address"); } - if (!Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + if (!checkConnectPermissionForDataDelivery( + service, source, TAG, "setActiveAudioDevicePolicy")) { return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION; } @@ -2157,7 +2153,8 @@ class AdapterServiceBinder extends IBluetooth.Stub { if (!BluetoothAdapter.checkBluetoothAddress(device.getAddress())) { throw new IllegalArgumentException("device cannot have an invalid address"); } - if (!Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + if (!checkConnectPermissionForDataDelivery( + service, source, TAG, "getActiveAudioDevicePolicy")) { return BluetoothDevice.ACTIVE_AUDIO_DEVICE_POLICY_DEFAULT; } @@ -2179,8 +2176,8 @@ class AdapterServiceBinder extends IBluetooth.Stub { if (!BluetoothAdapter.checkBluetoothAddress(device.getAddress())) { throw new IllegalArgumentException("device cannot have an invalid address"); } - if (!Utils.checkConnectPermissionForDataDelivery( - service, source, "AdapterService setMicrophonePreferredForCalls")) { + if (!checkConnectPermissionForDataDelivery( + service, source, TAG, "setMicrophonePreferredForCalls")) { return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION; } @@ -2202,8 +2199,8 @@ class AdapterServiceBinder extends IBluetooth.Stub { if (!BluetoothAdapter.checkBluetoothAddress(device.getAddress())) { throw new IllegalArgumentException("device cannot have an invalid address"); } - if (!Utils.checkConnectPermissionForDataDelivery( - service, source, "AdapterService isMicrophonePreferredForCalls")) { + if (!checkConnectPermissionForDataDelivery( + service, source, TAG, "isMicrophonePreferredForCalls")) { return true; } @@ -2256,8 +2253,7 @@ class AdapterServiceBinder extends IBluetooth.Stub { if (!BluetoothAdapter.checkBluetoothAddress(device.getAddress())) { throw new IllegalArgumentException("device cannot have an invalid address"); } - if (!Utils.checkConnectPermissionForDataDelivery( - service, source, "AdapterService getKeyMissingCount")) { + if (!checkConnectPermissionForDataDelivery(service, source, TAG, "getKeyMissingCount")) { return -1; } diff --git a/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java b/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java index 456545a42a..c7e1b3eccd 100644 --- a/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java +++ b/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java @@ -27,6 +27,7 @@ import static com.android.modules.utils.build.SdkLevel.isAtLeastV; import static java.util.Objects.requireNonNullElseGet; +import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.annotation.SuppressLint; import android.app.Activity; @@ -43,8 +44,11 @@ import android.bluetooth.BluetoothProtoEnums; import android.bluetooth.BluetoothSinkAudioPolicy; import android.bluetooth.BluetoothUtils; import android.bluetooth.IBluetoothConnectionCallback; +import android.content.AttributionSource; import android.content.Intent; +import android.content.pm.Attribution; import android.net.MacAddress; +import android.os.Build; import android.os.Handler; import android.os.Looper; import android.os.Message; @@ -64,9 +68,13 @@ import com.android.modules.utils.build.SdkLevel; import java.nio.charset.StandardCharsets; import java.util.ArrayDeque; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.function.Predicate; @@ -329,6 +337,7 @@ public class RemoteDevices { } class DeviceProperties { + private static final int MAX_PACKAGE_NAMES = 4; private String mName; private byte[] mAddress; private String mIdentityAddress; @@ -354,6 +363,16 @@ public class RemoteDevices { @VisibleForTesting boolean mHfpBatteryIndicator = false; private BluetoothSinkAudioPolicy mAudioPolicy; + // LRU cache of package names associated to this device + private final Set<String> mPackages = + Collections.newSetFromMap( + new LinkedHashMap<String, Boolean>() { + // This is called on every add. Returning true removes the eldest entry. + protected boolean removeEldestEntry(Map.Entry<String, Boolean> eldest) { + return size() >= MAX_PACKAGE_NAMES; + } + }); + DeviceProperties() { mBondState = BluetoothDevice.BOND_NONE; } @@ -858,6 +877,22 @@ public class RemoteDevices { return mModelName; } } + + @NonNull + public String[] getPackages() { + synchronized (mObject) { + return mPackages.toArray(new String[0]); + } + } + + public void addPackage(String packageName) { + synchronized (mObject) { + // Removing the package ensures that the LRU cache order is updated. Adding it back + // will make it the newest. + mPackages.remove(packageName); + mPackages.add(packageName); + } + } } private void sendUuidIntent(BluetoothDevice device, DeviceProperties prop, boolean success) { @@ -1606,6 +1641,28 @@ public class RemoteDevices { new String[] {BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED}, Utils.getTempBroadcastOptions()); } + + // Some apps are not able to handle the key missing broadcast, so we need to remove + // the bond to prevent them from misbehaving. + // TODO (b/402854328): Remove when the misbehaving apps are updated + if (bondLossIopFixNeeded(bluetoothDevice)) { + DeviceProperties deviceProperties = getDeviceProperties(bluetoothDevice); + if (deviceProperties == null) { + return; + } + String[] packages = deviceProperties.getPackages(); + if (packages.length == 0) { + return; + } + + Log.w( + TAG, + "Removing device: " + + bluetoothDevice + + "on behalf of: " + + Arrays.toString(packages)); + bluetoothDevice.removeBond(); + } } } @@ -1992,6 +2049,52 @@ public class RemoteDevices { device, batteryChargeIndicatorToPercentage(batteryLevel), /* isBas= */ false); } + private static final String[] BOND_LOSS_IOP_PACKAGES = { + "com.sjm.crmd.patientApp_Android_", "com.abbott.crm.ngq.patient.", + }; + + private static final Set<String> BOND_LOSS_IOP_DEVICE_NAMES = Set.of("CM", "DM"); + + // TODO (b/402854328): Remove when the misbehaving apps are updated + public boolean bondLossIopFixNeeded(BluetoothDevice device) { + DeviceProperties deviceProperties = getDeviceProperties(device); + if (deviceProperties == null) { + return false; + } + + String deviceName = deviceProperties.getName(); + if (deviceName == null) { + return false; + } + + String[] packages = deviceProperties.getPackages(); + if (packages.length == 0) { + return false; + } + + if (!BOND_LOSS_IOP_DEVICE_NAMES.contains(deviceName)) { + return false; + } + + for (String iopFixPackage : BOND_LOSS_IOP_PACKAGES) { + for (String packageName : packages) { + if (packageName.contains(iopFixPackage) + && !Utils.checkCallerTargetSdk( + mAdapterService, packageName, Build.VERSION_CODES.BAKLAVA)) { + Log.w( + TAG, + "bondLossIopFixNeeded(): " + + deviceName + + " IOP fix needed for package " + + packageName); + return true; + } + } + } + + return false; + } + private static void errorLog(String msg) { Log.e(TAG, msg); } diff --git a/android/app/src/com/android/bluetooth/gatt/GattService.java b/android/app/src/com/android/bluetooth/gatt/GattService.java index aaa00b45df..c0ca2969d4 100644 --- a/android/app/src/com/android/bluetooth/gatt/GattService.java +++ b/android/app/src/com/android/bluetooth/gatt/GattService.java @@ -1593,9 +1593,11 @@ public class GattService extends ProfileService { int preferredMtu = 0; - // Some applications expect MTU to be exchanged immediately on connections String packageName = source.getPackageName(); if (packageName != null) { + mAdapterService.addAssociatedPackage(getDevice(address), packageName); + + // Some apps expect MTU to be exchanged immediately on connections for (Map.Entry<String, Integer> entry : EARLY_MTU_EXCHANGE_PACKAGES.entrySet()) { if (packageName.contains(entry.getKey())) { preferredMtu = entry.getValue(); diff --git a/android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java b/android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java index 6af6323083..a884944bac 100644 --- a/android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java +++ b/android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java @@ -1052,7 +1052,8 @@ public class HearingAidService extends ProfileService { if (!Utils.checkServiceAvailable(service, TAG) || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG) - || !Utils.checkScanPermissionForDataDelivery(service, source, TAG)) { + || !Utils.checkScanPermissionForDataDelivery( + service, source, TAG, "getAdvertisementServiceData")) { return null; } diff --git a/android/app/src/com/android/bluetooth/le_scan/AppScanStats.java b/android/app/src/com/android/bluetooth/le_scan/AppScanStats.java index 97e1f5ede5..b5090eabd7 100644 --- a/android/app/src/com/android/bluetooth/le_scan/AppScanStats.java +++ b/android/app/src/com/android/bluetooth/le_scan/AppScanStats.java @@ -195,6 +195,7 @@ class AppScanStats { mTimeProvider = requireNonNull(timeProvider); } + @Nullable private synchronized LastScan getScanFromScannerId(int scannerId) { return mOngoingScans.get(scannerId); } @@ -530,7 +531,7 @@ class AppScanStats { convertScanType(getScanFromScannerId(scannerId)), BluetoothStatsLog.LE_SCAN_ABUSED__LE_SCAN_ABUSE_REASON__REASON_SCAN_TIMEOUT, scanTimeoutMillis, - getScanFromScannerId(scannerId).getAttributionTag()); + getAttributionTagFromScannerId(scannerId)); } MetricsLogger.getInstance() .cacheCount(BluetoothProtoEnums.LE_SCAN_ABUSE_COUNT_SCAN_TIMEOUT, 1); @@ -546,7 +547,7 @@ class AppScanStats { convertScanType(getScanFromScannerId(scannerId)), BluetoothStatsLog.LE_SCAN_ABUSED__LE_SCAN_ABUSE_REASON__REASON_HW_FILTER_NA, numOfFilterSupported, - getScanFromScannerId(scannerId).getAttributionTag()); + getAttributionTagFromScannerId(scannerId)); } MetricsLogger.getInstance() .cacheCount(BluetoothProtoEnums.LE_SCAN_ABUSE_COUNT_HW_FILTER_NOT_AVAILABLE, 1); @@ -563,7 +564,7 @@ class AppScanStats { BluetoothStatsLog .LE_SCAN_ABUSED__LE_SCAN_ABUSE_REASON__REASON_TRACKING_HW_FILTER_NA, numOfTrackableAdv, - getScanFromScannerId(scannerId).getAttributionTag()); + getAttributionTagFromScannerId(scannerId)); } MetricsLogger.getInstance() .cacheCount( @@ -596,7 +597,7 @@ class AppScanStats { sRadioScanIntervalMs = scanIntervalMs; sIsRadioStarted = true; sRadioScanAppImportance = stats.mAppImportance; - sRadioScanAttributionTag = stats.getScanFromScannerId(scannerId).getAttributionTag(); + sRadioScanAttributionTag = stats.getAttributionTagFromScannerId(scannerId); } return true; } @@ -849,6 +850,11 @@ class AppScanStats { < LARGE_SCAN_TIME_GAP_MS); } + private String getAttributionTagFromScannerId(int scannerId) { + LastScan scan = getScanFromScannerId(scannerId); + return scan == null ? "" : scan.getAttributionTag(); + } + private static String filterToStringWithoutNullParam(ScanFilter filter) { StringBuilder filterString = new StringBuilder("BluetoothLeScanFilter ["); if (filter.getDeviceName() != null) { diff --git a/android/app/src/com/android/bluetooth/le_scan/ScanController.java b/android/app/src/com/android/bluetooth/le_scan/ScanController.java index 82b8e10dd7..2fc20d8314 100644 --- a/android/app/src/com/android/bluetooth/le_scan/ScanController.java +++ b/android/app/src/com/android/bluetooth/le_scan/ScanController.java @@ -22,6 +22,7 @@ import static android.Manifest.permission.UPDATE_DEVICE_STATS; import static android.bluetooth.BluetoothUtils.extractBytes; import static com.android.bluetooth.Utils.checkCallerTargetSdk; +import static com.android.bluetooth.Utils.checkScanPermissionForDataDelivery; import static com.android.bluetooth.flags.Flags.leaudioBassScanWithInternalScanController; import static java.util.Objects.requireNonNull; @@ -1082,8 +1083,7 @@ public class ScanController { @RequiresPermission(BLUETOOTH_SCAN) void registerScanner( IScannerCallback callback, WorkSource workSource, AttributionSource source) { - if (!Utils.checkScanPermissionForDataDelivery( - mAdapterService, source, "ScanController registerScanner")) { + if (!checkScanPermissionForDataDelivery(mAdapterService, source, TAG, "registerScanner")) { return; } @@ -1116,8 +1116,8 @@ public class ScanController { @RequiresPermission(BLUETOOTH_SCAN) void unregisterScanner(int scannerId, AttributionSource source) { - if (!Utils.checkScanPermissionForDataDelivery( - mAdapterService, source, "ScanController unregisterScanner")) { + if (!checkScanPermissionForDataDelivery( + mAdapterService, source, TAG, "unregisterScanner")) { return; } @@ -1163,7 +1163,7 @@ public class ScanController { List<ScanFilter> filters, AttributionSource source) { Log.d(TAG, "Start scan with filters"); - if (!Utils.checkScanPermissionForDataDelivery(mAdapterService, source, "Starting scan.")) { + if (!checkScanPermissionForDataDelivery(mAdapterService, source, TAG, "startScan")) { return; } @@ -1255,7 +1255,8 @@ public class ScanController { List<ScanFilter> filters, AttributionSource source) { Log.d(TAG, "Start scan with filters, for PendingIntent"); - if (!Utils.checkScanPermissionForDataDelivery(mAdapterService, source, "Starting scan.")) { + if (!checkScanPermissionForDataDelivery( + mAdapterService, source, TAG, "registerPiAndStartScan")) { return; } @@ -1359,8 +1360,8 @@ public class ScanController { @RequiresPermission(BLUETOOTH_SCAN) void flushPendingBatchResults(int scannerId, AttributionSource source) { - if (!Utils.checkScanPermissionForDataDelivery( - mAdapterService, source, "ScanController flushPendingBatchResults")) { + if (!checkScanPermissionForDataDelivery( + mAdapterService, source, TAG, "flushPendingBatchResults")) { return; } flushPendingBatchResultsInternal(scannerId); @@ -1373,8 +1374,7 @@ public class ScanController { @RequiresPermission(BLUETOOTH_SCAN) void stopScan(int scannerId, AttributionSource source) { - if (!Utils.checkScanPermissionForDataDelivery( - mAdapterService, source, "ScanController stopScan")) { + if (!checkScanPermissionForDataDelivery(mAdapterService, source, TAG, "stopScan")) { return; } stopScanInternal(scannerId); @@ -1396,8 +1396,7 @@ public class ScanController { @RequiresPermission(BLUETOOTH_SCAN) void stopScan(PendingIntent intent, AttributionSource source) { - if (!Utils.checkScanPermissionForDataDelivery( - mAdapterService, source, "ScanController stopScan")) { + if (!checkScanPermissionForDataDelivery(mAdapterService, source, TAG, "stopScan")) { return; } stopScanInternal(intent); @@ -1426,8 +1425,7 @@ public class ScanController { int timeout, IPeriodicAdvertisingCallback callback, AttributionSource source) { - if (!Utils.checkScanPermissionForDataDelivery( - mAdapterService, source, "ScanController registerSync")) { + if (!checkScanPermissionForDataDelivery(mAdapterService, source, TAG, "registerSync")) { return; } mPeriodicScanManager.startSync(scanResult, skip, timeout, callback); @@ -1435,8 +1433,7 @@ public class ScanController { @RequiresPermission(BLUETOOTH_SCAN) void unregisterSync(IPeriodicAdvertisingCallback callback, AttributionSource source) { - if (!Utils.checkScanPermissionForDataDelivery( - mAdapterService, source, "ScanController unregisterSync")) { + if (!checkScanPermissionForDataDelivery(mAdapterService, source, TAG, "unregisterSync")) { return; } mPeriodicScanManager.stopSync(callback); @@ -1445,8 +1442,7 @@ public class ScanController { @RequiresPermission(BLUETOOTH_SCAN) void transferSync( BluetoothDevice bda, int serviceData, int syncHandle, AttributionSource source) { - if (!Utils.checkScanPermissionForDataDelivery( - mAdapterService, source, "ScanController transferSync")) { + if (!checkScanPermissionForDataDelivery(mAdapterService, source, TAG, "transferSync")) { return; } mPeriodicScanManager.transferSync(bda, serviceData, syncHandle); @@ -1459,8 +1455,7 @@ public class ScanController { int advHandle, IPeriodicAdvertisingCallback callback, AttributionSource source) { - if (!Utils.checkScanPermissionForDataDelivery( - mAdapterService, source, "ScanController transferSetInfo")) { + if (!checkScanPermissionForDataDelivery(mAdapterService, source, TAG, "transferSetInfo")) { return; } mPeriodicScanManager.transferSetInfo(bda, serviceData, advHandle, callback); @@ -1468,8 +1463,8 @@ public class ScanController { @RequiresPermission(BLUETOOTH_SCAN) int numHwTrackFiltersAvailable(AttributionSource source) { - if (!Utils.checkScanPermissionForDataDelivery( - mAdapterService, source, "ScanController numHwTrackFiltersAvailable")) { + if (!checkScanPermissionForDataDelivery( + mAdapterService, source, TAG, "numHwTrackFiltersAvailable")) { return 0; } return (mAdapterService.getTotalNumOfTrackableAdvertisements() diff --git a/android/pandora/test/main.py b/android/pandora/test/main.py index d5c5da0bad..7e49321932 100644 --- a/android/pandora/test/main.py +++ b/android/pandora/test/main.py @@ -25,6 +25,7 @@ import avatar.cases.security_test import gatt_test import hap_test import hfpclient_test +import rfcomm_test import sdp_test from pairing import _test_class_list as _pairing_test_class_list @@ -81,6 +82,7 @@ _TEST_CLASSES_LIST = [ hap_test.HapTest, asha_test.AshaTest, hfpclient_test.HfpClientTest, + rfcomm_test.RfcommTest, ] + _pairing_test_class_list diff --git a/android/pandora/test/rfcomm_test.py b/android/pandora/test/rfcomm_test.py new file mode 100644 index 0000000000..4409b02e25 --- /dev/null +++ b/android/pandora/test/rfcomm_test.py @@ -0,0 +1,110 @@ +# Copyright 2025 Google LLC +# +# 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 +# +# https://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. + +import asyncio +import avatar +import grpc +import logging + +from avatar import PandoraDevices +from avatar.aio import asynchronous +from avatar.pandora_client import BumblePandoraClient, PandoraClient +from bumble.rfcomm import Server +from bumble_experimental.rfcomm import RFCOMMService +from mobly import base_test, test_runner +from mobly.asserts import assert_equal # type: ignore +from mobly.asserts import assert_in # type: ignore +from mobly.asserts import assert_is_not_none # type: ignore +from mobly.asserts import fail # type: ignore +from pandora_experimental.rfcomm_grpc_aio import RFCOMM +from pandora_experimental.rfcomm_pb2 import ( + AcceptConnectionRequest, + RxRequest, + StartServerRequest, + StopServerRequest, + TxRequest, +) +from typing import Optional, Tuple + +SERIAL_PORT_UUID = "00001101-0000-1000-8000-00805F9B34FB" +TEST_SERVER_NAME = "RFCOMM-Server" + + +class RfcommTest(base_test.BaseTestClass): + devices: Optional[PandoraDevices] = None + dut: PandoraClient + ref: BumblePandoraClient + + def setup_class(self) -> None: + self.devices = PandoraDevices(self) + self.dut, ref, *_ = self.devices + assert isinstance(ref, BumblePandoraClient) + self.ref = ref + # Enable BR/EDR mode and SSP for Bumble devices. + self.ref.config.setdefault('classic_enabled', True) + self.ref.config.setdefault('classic_ssp_enabled', True) + self.ref.config.setdefault( + 'server', + { + 'io_capability': 'no_output_no_input', + }, + ) + + def teardown_class(self) -> None: + if self.devices: + self.devices.stop_all() + + @avatar.asynchronous + async def setup_test(self) -> None: + await asyncio.gather(self.dut.reset(), self.ref.reset()) + + ref_server = Server(self.ref.device) + self.ref.rfcomm = RFCOMMService(self.ref.device, ref_server) + self.dut.rfcomm = RFCOMM(channel=self.dut.aio.channel) + + @avatar.asynchronous + async def test_client_connect_and_exchange_data(self) -> None: + # dut is client, ref is server + context = grpc.ServicerContext + server = await self.ref.rfcomm.StartServer(StartServerRequest(name=TEST_SERVER_NAME, uuid=SERIAL_PORT_UUID), + context=context) + # Convert StartServerResponse to its server + server = server.server + rfc_dut_ref, rfc_ref_dut = await asyncio.gather( + self.dut.rfcomm.ConnectToServer(address=self.ref.address, uuid=SERIAL_PORT_UUID), + self.ref.rfcomm.AcceptConnection(request=AcceptConnectionRequest(server=server), context=context)) + # Convert Responses to their corresponding RfcommConnection + rfc_dut_ref = rfc_dut_ref.connection + rfc_ref_dut = rfc_ref_dut.connection + + # Transmit data + tx_data = b'Data from dut to ref' + await self.dut.rfcomm.Send(data=tx_data, connection=rfc_dut_ref) + ref_receive = await self.ref.rfcomm.Receive(request=RxRequest(connection=rfc_ref_dut), context=context) + assert_equal(ref_receive.data, tx_data) + + # Receive data + rx_data = b'Data from ref to dut' + await self.ref.rfcomm.Send(request=TxRequest(connection=rfc_ref_dut, data=rx_data), context=context) + dut_receive = await self.dut.rfcomm.Receive(connection=rfc_dut_ref) + assert_equal(dut_receive.data.rstrip(b'\x00'), rx_data) + + # Disconnect (from dut) + await self.dut.rfcomm.Disconnect(connection=rfc_dut_ref) + await self.ref.rfcomm.StopServer(request=StopServerRequest(server=server), context=context) + + +if __name__ == '__main__': + logging.basicConfig(level=logging.DEBUG) + test_runner.main() # type: ignore diff --git a/apex/Android.bp b/apex/Android.bp index c2aabcf0b8..bf75163768 100644 --- a/apex/Android.bp +++ b/apex/Android.bp @@ -84,7 +84,6 @@ apex { ], key: "com.android.bt.key", certificate: ":com.android.bt.certificate", - updatable: true, compressible: false, visibility: ["//packages/modules/common/build"], } diff --git a/flags/sockets.aconfig b/flags/sockets.aconfig index 2eb23b1fcb..6b31e06705 100644 --- a/flags/sockets.aconfig +++ b/flags/sockets.aconfig @@ -92,3 +92,13 @@ flag { purpose: PURPOSE_BUGFIX } } + +flag { + name: "fix_lecoc_socket_available" + namespace: "bluetooth" + description: "Fix Bluetooth Socket available API for LECOC socket" + bug: "402536099" + metadata { + purpose: PURPOSE_BUGFIX + } +} diff --git a/offload/leaudio/hci/proxy.rs b/offload/leaudio/hci/proxy.rs index 933389d315..adc2dbd34d 100644 --- a/offload/leaudio/hci/proxy.rs +++ b/offload/leaudio/hci/proxy.rs @@ -195,10 +195,16 @@ impl Module for LeAudioModule { ); } - Ok(Command::LeSetupIsoDataPath(ref c)) if c.data_path_id == DATA_PATH_ID_SOFTWARE => { + Ok(Command::LeSetupIsoDataPath(ref c)) if c.data_path_id == DATA_PATH_ID_SOFTWARE => 'command: { assert_eq!(c.data_path_direction, hci::LeDataPathDirection::Input); let mut state = self.state.lock().unwrap(); - let stream = state.stream.get_mut(&c.connection_handle).unwrap(); + let Some(stream) = state.stream.get_mut(&c.connection_handle) else { + log::warn!( + "Setup ISO Data Path on non existing BIS/CIS handle: 0x{:03x}", + c.connection_handle + ); + break 'command; + }; stream.state = StreamState::Enabling; // Phase 1 limitation: The controller does not implement HCI Link Feedback event, @@ -209,6 +215,16 @@ impl Module for LeAudioModule { return; } + Ok(Command::LeRemoveIsoDataPath(ref c)) => { + let mut state = self.state.lock().unwrap(); + if state.stream.get_mut(&c.connection_handle).is_none() { + log::warn!( + "Remove ISO Data Path on non existing BIS/CIS handle: 0x{:03x}", + c.connection_handle + ); + } + } + _ => (), } @@ -250,7 +266,9 @@ impl Module for LeAudioModule { ReturnParameters::LeSetupIsoDataPath(ref ret) => 'event: { let mut state = self.state.lock().unwrap(); - let stream = state.stream.get_mut(&ret.connection_handle).unwrap(); + let Some(stream) = state.stream.get_mut(&ret.connection_handle) else { + break 'event; + }; stream.state = if stream.state == StreamState::Enabling && ret.status == Status::Success { StreamState::Enabled @@ -278,9 +296,11 @@ impl Module for LeAudioModule { ); } - ReturnParameters::LeRemoveIsoDataPath(ref ret) if ret.status == Status::Success => { + ReturnParameters::LeRemoveIsoDataPath(ref ret) if ret.status == Status::Success => 'event: { let mut state = self.state.lock().unwrap(); - let stream = state.stream.get_mut(&ret.connection_handle).unwrap(); + let Some(stream) = state.stream.get_mut(&ret.connection_handle) else { + break 'event; + }; if stream.state == StreamState::Enabled { Service::stop_stream(ret.connection_handle); } diff --git a/system/btif/Android.bp b/system/btif/Android.bp index 0eb097dca7..82544f36ba 100644 --- a/system/btif/Android.bp +++ b/system/btif/Android.bp @@ -122,7 +122,6 @@ cc_library_static { "src/btif_keystore.cc", "src/btif_le_audio.cc", "src/btif_le_audio_broadcaster.cc", - "src/btif_metrics_logging.cc", "src/btif_pan.cc", "src/btif_profile_queue.cc", "src/btif_profile_queue.cc", diff --git a/system/btif/BUILD.gn b/system/btif/BUILD.gn index ea6a0f6fbc..9def60989b 100644 --- a/system/btif/BUILD.gn +++ b/system/btif/BUILD.gn @@ -64,7 +64,6 @@ static_library("btif") { "src/btif_jni_task.cc", "src/btif_keystore.cc", "src/btif_le_audio.cc", - "src/btif_metrics_logging.cc", "src/btif_pan.cc", "src/btif_profile_queue.cc", "src/btif_profile_storage.cc", diff --git a/system/btif/include/btif_metrics_logging.h b/system/btif/include/btif_metrics_logging.h deleted file mode 100644 index 94f7a66b79..0000000000 --- a/system/btif/include/btif_metrics_logging.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2021 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. - */ - -#pragma once - -#include <frameworks/proto_logging/stats/enums/bluetooth/enums.pb.h> -#include <frameworks/proto_logging/stats/enums/bluetooth/hci/enums.pb.h> - -#include "main/shim/metric_id_api.h" -#include "types/raw_address.h" - -void log_a2dp_audio_underrun_event(const RawAddress& address, uint64_t encoding_interval_millis, - int num_missing_pcm_bytes); - -void log_a2dp_audio_overrun_event(const RawAddress& address, uint64_t encoding_interval_millis, - int num_dropped_buffers, int num_dropped_encoded_frames, - int num_dropped_encoded_bytes); - -void log_a2dp_playback_event(const RawAddress& address, int playback_state, int audio_coding_mode); - -void log_a2dp_session_metrics_event(const RawAddress& address, int64_t audio_duration_ms, - int media_timer_min_ms, int media_timer_max_ms, - int media_timer_avg_ms, int total_scheduling_count, - int buffer_overruns_max_count, int buffer_overruns_total, - float buffer_underruns_average, int buffer_underruns_count, - int64_t codec_index, bool is_a2dp_offload); - -void log_read_rssi_result(const RawAddress& address, uint16_t handle, uint32_t cmd_status, - int8_t rssi); - -void log_read_failed_contact_counter_result(const RawAddress& address, uint16_t handle, - uint32_t cmd_status, int32_t failed_contact_counter); - -void log_read_tx_power_level_result(const RawAddress& address, uint16_t handle, uint32_t cmd_status, - int32_t transmit_power_level); - -void log_counter_metrics_btif(android::bluetooth::CodePathCounterKeyEnum key, int64_t value); - -void log_socket_connection_state(const RawAddress& address, int port, int type, - android::bluetooth::SocketConnectionstateEnum connection_state, - int64_t tx_bytes, int64_t rx_bytes, int uid, int server_port, - android::bluetooth::SocketRoleEnum socket_role, - uint64_t connection_duration_ms, - android::bluetooth::SocketErrorEnum error_code, - bool is_hardware_offload); - -bool init_metric_id_allocator(const std::unordered_map<RawAddress, int>& paired_device_map, - bluetooth::shim::CallbackLegacy save_id_callback, - bluetooth::shim::CallbackLegacy forget_device_callback); - -bool close_metric_id_allocator(); - -int allocate_metric_id_from_metric_id_allocator(const RawAddress&); - -int save_metric_id_from_metric_id_allocator(const RawAddress&); - -void forget_device_from_metric_id_allocator(const RawAddress&); - -bool is_valid_id_from_metric_id_allocator(const int id); diff --git a/system/btif/src/bluetooth.cc b/system/btif/src/bluetooth.cc index 5741b05c4f..9badbc9ab6 100644 --- a/system/btif/src/bluetooth.cc +++ b/system/btif/src/bluetooth.cc @@ -71,7 +71,6 @@ #include "btif/include/btif_hh.h" #include "btif/include/btif_keystore.h" #include "btif/include/btif_le_audio.h" -#include "btif/include/btif_metrics_logging.h" #include "btif/include/btif_pan.h" #include "btif/include/btif_profile_storage.h" #include "btif/include/btif_rc.h" @@ -99,6 +98,7 @@ #include "hardware/bt_vc.h" #include "internal_include/bt_target.h" #include "main/shim/dumpsys.h" +#include "main/shim/metric_id_api.h" #include "os/parameter_provider.h" #include "osi/include/alarm.h" #include "osi/include/allocator.h" @@ -1099,7 +1099,7 @@ static std::string obfuscate_address(const RawAddress& address) { } static int get_metric_id(const RawAddress& address) { - return allocate_metric_id_from_metric_id_allocator(address); + return bluetooth::shim::AllocateIdFromMetricIdAllocator(address); } static int set_dynamic_audio_buffer_size(int codec, int size) { diff --git a/system/btif/src/btif_a2dp_source.cc b/system/btif/src/btif_a2dp_source.cc index bf4c00c0d5..20805a92bd 100644 --- a/system/btif/src/btif_a2dp_source.cc +++ b/system/btif/src/btif_a2dp_source.cc @@ -46,13 +46,13 @@ #include "btif_av_co.h" #include "btif_common.h" #include "btif_hf.h" -#include "btif_metrics_logging.h" #include "btm_iso_api.h" #include "common/message_loop_thread.h" #include "common/metrics.h" #include "common/repeating_timer.h" #include "common/time_util.h" #include "hardware/bt_av.h" +#include "main/shim/metrics_api.h" #include "osi/include/allocator.h" #include "osi/include/fixed_queue.h" #include "osi/include/wakelock.h" @@ -931,8 +931,9 @@ static uint32_t btif_a2dp_source_read_callback(uint8_t* p_buf, uint32_t len) { btif_a2dp_source_cb.stats.media_read_total_underflow_count++; btif_a2dp_source_cb.stats.media_read_last_underflow_us = bluetooth::common::time_get_os_boottime_us(); - log_a2dp_audio_underrun_event(btif_av_source_active_peer(), - btif_a2dp_source_cb.encoder_interval_ms, len - bytes_read); + bluetooth::shim::LogMetricA2dpAudioUnderrunEvent(btif_av_source_active_peer(), + btif_a2dp_source_cb.encoder_interval_ms, + len - bytes_read); } return bytes_read; @@ -984,9 +985,9 @@ static bool btif_a2dp_source_enqueue_callback(BT_HDR* p_buf, size_t frames_n, osi_free(p_data); } } - log_a2dp_audio_overrun_event(btif_av_source_active_peer(), - btif_a2dp_source_cb.encoder_interval_ms, drop_n, - num_dropped_encoded_frames, num_dropped_encoded_bytes); + bluetooth::shim::LogMetricA2dpAudioOverrunEvent( + btif_av_source_active_peer(), btif_a2dp_source_cb.encoder_interval_ms, drop_n, + num_dropped_encoded_frames, num_dropped_encoded_bytes); // Request additional debug info if we had to flush buffers RawAddress peer_bda = btif_av_source_active_peer(); @@ -1276,12 +1277,12 @@ static void btif_a2dp_source_update_metrics(void) { } if (metrics.audio_duration_ms != -1) { - log_a2dp_session_metrics_event(btif_av_source_active_peer(), metrics.audio_duration_ms, - metrics.media_timer_min_ms, metrics.media_timer_max_ms, - metrics.media_timer_avg_ms, metrics.total_scheduling_count, - metrics.buffer_overruns_max_count, metrics.buffer_overruns_total, - metrics.buffer_underruns_average, metrics.buffer_underruns_count, - metrics.codec_index, metrics.is_a2dp_offload); + bluetooth::shim::LogMetricA2dpSessionMetricsEvent( + btif_av_source_active_peer(), metrics.audio_duration_ms, metrics.media_timer_min_ms, + metrics.media_timer_max_ms, metrics.media_timer_avg_ms, metrics.total_scheduling_count, + metrics.buffer_overruns_max_count, metrics.buffer_overruns_total, + metrics.buffer_underruns_average, metrics.buffer_underruns_count, metrics.codec_index, + metrics.is_a2dp_offload); } } @@ -1301,8 +1302,9 @@ static void btm_read_rssi_cb(void* data) { return; } - log_read_rssi_result(result->rem_bda, bluetooth::common::kUnknownConnectionHandle, - result->hci_status, result->rssi); + bluetooth::shim::LogMetricReadRssiResult(result->rem_bda, + bluetooth::common::kUnknownConnectionHandle, + result->hci_status, result->rssi); log::warn("device: {}, rssi: {}", result->rem_bda, result->rssi); } @@ -1318,9 +1320,9 @@ static void btm_read_failed_contact_counter_cb(void* data) { log::error("unable to read Failed Contact Counter (status {})", result->status); return; } - log_read_failed_contact_counter_result(result->rem_bda, - bluetooth::common::kUnknownConnectionHandle, - result->hci_status, result->failed_contact_counter); + bluetooth::shim::LogMetricReadFailedContactCounterResult( + result->rem_bda, bluetooth::common::kUnknownConnectionHandle, result->hci_status, + result->failed_contact_counter); log::warn("device: {}, Failed Contact Counter: {}", result->rem_bda, result->failed_contact_counter); @@ -1337,8 +1339,9 @@ static void btm_read_tx_power_cb(void* data) { log::error("unable to read Tx Power (status {})", result->status); return; } - log_read_tx_power_level_result(result->rem_bda, bluetooth::common::kUnknownConnectionHandle, - result->hci_status, result->tx_power); + bluetooth::shim::LogMetricReadTxPowerLevelResult(result->rem_bda, + bluetooth::common::kUnknownConnectionHandle, + result->hci_status, result->tx_power); log::warn("device: {}, Tx Power: {}", result->rem_bda, result->tx_power); } diff --git a/system/btif/src/btif_av.cc b/system/btif/src/btif_av.cc index 101ebcc4a0..2ee3be4c88 100644 --- a/system/btif/src/btif_av.cc +++ b/system/btif/src/btif_av.cc @@ -52,18 +52,17 @@ #include "btif/include/btif_a2dp_source.h" #include "btif/include/btif_av_co.h" #include "btif/include/btif_common.h" -#include "btif/include/btif_metrics_logging.h" #include "btif/include/btif_profile_queue.h" #include "btif/include/btif_rc.h" #include "btif/include/btif_util.h" #include "btif/include/stack_manager_t.h" -#include "btif_metrics_logging.h" #include "common/state_machine.h" #include "device/include/device_iot_conf_defs.h" #include "device/include/device_iot_config.h" #include "hardware/bluetooth.h" #include "hardware/bt_av.h" #include "include/hardware/bt_rc.h" +#include "main/shim/metrics_api.h" #include "osi/include/alarm.h" #include "osi/include/allocator.h" #include "osi/include/properties.h" @@ -1985,7 +1984,7 @@ bool BtifAvStateMachine::StateOpening::ProcessEvent(uint32_t event, void* p_data // incoming/outgoing connect/disconnect requests. log::warn("Peer {} : event={}: transitioning to Idle due to ACL Disconnect", peer_.PeerAddress(), BtifAvEvent::EventName(event)); - log_counter_metrics_btif( + bluetooth::shim::CountCounterMetrics( android::bluetooth::CodePathCounterKeyEnum::A2DP_CONNECTION_ACL_DISCONNECTED, 1); btif_report_connection_state(peer_.PeerAddress(), BTAV_CONNECTION_STATE_DISCONNECTED, bt_status_t::BT_STATUS_FAIL, BTA_AV_FAIL, @@ -1998,7 +1997,7 @@ bool BtifAvStateMachine::StateOpening::ProcessEvent(uint32_t event, void* p_data case BTA_AV_REJECT_EVT: log::warn("Peer {} : event={} flags={}", peer_.PeerAddress(), BtifAvEvent::EventName(event), peer_.FlagsToString()); - log_counter_metrics_btif( + bluetooth::shim::CountCounterMetrics( android::bluetooth::CodePathCounterKeyEnum::A2DP_CONNECTION_REJECT_EVT, 1); btif_report_connection_state(peer_.PeerAddress(), BTAV_CONNECTION_STATE_DISCONNECTED, bt_status_t::BT_STATUS_AUTH_REJECTED, BTA_AV_FAIL, @@ -2080,7 +2079,7 @@ bool BtifAvStateMachine::StateOpening::ProcessEvent(uint32_t event, void* p_data btif_report_connection_state(peer_.PeerAddress(), BTAV_CONNECTION_STATE_CONNECTED, bt_status_t::BT_STATUS_SUCCESS, BTA_AV_SUCCESS, peer_.IsSource() ? A2dpType::kSink : A2dpType::kSource); - log_counter_metrics_btif( + bluetooth::shim::CountCounterMetrics( android::bluetooth::CodePathCounterKeyEnum::A2DP_CONNECTION_SUCCESS, 1); } else { if (btif_rc_is_connected_peer(peer_.PeerAddress())) { @@ -2099,7 +2098,7 @@ bool BtifAvStateMachine::StateOpening::ProcessEvent(uint32_t event, void* p_data btif_report_connection_state(peer_.PeerAddress(), BTAV_CONNECTION_STATE_DISCONNECTED, bt_status_t::BT_STATUS_FAIL, status, peer_.IsSource() ? A2dpType::kSink : A2dpType::kSource); - log_counter_metrics_btif( + bluetooth::shim::CountCounterMetrics( android::bluetooth::CodePathCounterKeyEnum::A2DP_CONNECTION_FAILURE, 1); } @@ -2139,8 +2138,8 @@ bool BtifAvStateMachine::StateOpening::ProcessEvent(uint32_t event, void* p_data "Peer {} : event={} : device is already connecting, ignore Connect " "request", peer_.PeerAddress(), BtifAvEvent::EventName(event)); - log_counter_metrics_btif(android::bluetooth::CodePathCounterKeyEnum::A2DP_ALREADY_CONNECTING, - 1); + bluetooth::shim::CountCounterMetrics( + android::bluetooth::CodePathCounterKeyEnum::A2DP_ALREADY_CONNECTING, 1); btif_queue_advance(); } break; @@ -2151,15 +2150,15 @@ bool BtifAvStateMachine::StateOpening::ProcessEvent(uint32_t event, void* p_data "Peer {} : event={} : device is already connecting, ignore incoming " "request", peer_.PeerAddress(), BtifAvEvent::EventName(event)); - log_counter_metrics_btif(android::bluetooth::CodePathCounterKeyEnum::A2DP_ALREADY_CONNECTING, - 1); + bluetooth::shim::CountCounterMetrics( + android::bluetooth::CodePathCounterKeyEnum::A2DP_ALREADY_CONNECTING, 1); } break; case BTIF_AV_OFFLOAD_START_REQ_EVT: log::error("Peer {} : event={}: stream is not Opened", peer_.PeerAddress(), BtifAvEvent::EventName(event)); btif_a2dp_on_offload_started(peer_.PeerAddress(), BTA_AV_FAIL); - log_counter_metrics_btif( + bluetooth::shim::CountCounterMetrics( android::bluetooth::CodePathCounterKeyEnum::A2DP_OFFLOAD_START_REQ_FAILURE, 1); break; @@ -2169,8 +2168,8 @@ bool BtifAvStateMachine::StateOpening::ProcessEvent(uint32_t event, void* p_data bt_status_t::BT_STATUS_FAIL, BTA_AV_FAIL, peer_.IsSource() ? A2dpType::kSink : A2dpType::kSource); peer_.StateMachine().TransitionTo(BtifAvStateMachine::kStateIdle); - log_counter_metrics_btif(android::bluetooth::CodePathCounterKeyEnum::A2DP_CONNECTION_CLOSE, - 1); + bluetooth::shim::CountCounterMetrics( + android::bluetooth::CodePathCounterKeyEnum::A2DP_CONNECTION_CLOSE, 1); DEVICE_IOT_CONFIG_ADDR_INT_ADD_ONE(peer_.PeerAddress(), IOT_CONF_KEY_A2DP_CONN_FAIL_COUNT); if (peer_.SelfInitiatedConnection()) { btif_queue_advance(); @@ -2184,7 +2183,7 @@ bool BtifAvStateMachine::StateOpening::ProcessEvent(uint32_t event, void* p_data peer_.IsSource() ? A2dpType::kSink : A2dpType::kSource); peer_.StateMachine().TransitionTo(BtifAvStateMachine::kStateIdle); DEVICE_IOT_CONFIG_ADDR_INT_ADD_ONE(peer_.PeerAddress(), IOT_CONF_KEY_A2DP_CONN_FAIL_COUNT); - log_counter_metrics_btif( + bluetooth::shim::CountCounterMetrics( android::bluetooth::CodePathCounterKeyEnum::A2DP_CONNECTION_DISCONNECTED, 1); if (peer_.SelfInitiatedConnection()) { btif_queue_advance(); @@ -2203,7 +2202,7 @@ bool BtifAvStateMachine::StateOpening::ProcessEvent(uint32_t event, void* p_data CHECK_RC_EVENT(event, reinterpret_cast<tBTA_AV*>(p_data)); default: - log_counter_metrics_btif( + bluetooth::shim::CountCounterMetrics( android::bluetooth::CodePathCounterKeyEnum::A2DP_CONNECTION_UNKNOWN_EVENT, 1); log::warn("Peer {} : Unhandled event={}", peer_.PeerAddress(), BtifAvEvent::EventName(event)); return false; @@ -2933,7 +2932,7 @@ static void btif_report_audio_state(const RawAddress& peer_address, btav_audio_s ? AudioCodingModeEnum::AUDIO_CODING_MODE_HARDWARE : AudioCodingModeEnum::AUDIO_CODING_MODE_SOFTWARE; - log_a2dp_playback_event(peer_address, playback_state, audio_coding_mode); + bluetooth::shim::LogMetricA2dpPlaybackEvent(peer_address, playback_state, audio_coding_mode); } void btif_av_report_source_codec_state( diff --git a/system/btif/src/btif_config.cc b/system/btif/src/btif_config.cc index 2ee8fe494d..9a0e50dea1 100644 --- a/system/btif/src/btif_config.cc +++ b/system/btif/src/btif_config.cc @@ -32,9 +32,10 @@ #include <unordered_map> #include "btif_keystore.h" -#include "btif_metrics_logging.h" #include "common/address_obfuscator.h" #include "main/shim/config.h" +#include "main/shim/metric_id_api.h" +#include "main/shim/metrics_api.h" #include "main/shim/shim.h" #include "storage/config_keys.h" #include "types/raw_address.h" @@ -111,7 +112,7 @@ static void init_metric_id_allocator() { // there is one metric id under this mac_address int id = 0; btif_config_get_int(addr_str, BTIF_STORAGE_KEY_METRICS_ID_KEY, &id); - if (is_valid_id_from_metric_id_allocator(id)) { + if (bluetooth::shim::IsValidIdFromMetricIdAllocator(id)) { paired_device_map[mac_address] = id; is_valid_id_found = true; } @@ -128,15 +129,15 @@ static void init_metric_id_allocator() { auto forget_device_callback = [](const RawAddress& address, const int /* id */) { return btif_config_remove(address.ToString(), BTIF_STORAGE_KEY_METRICS_ID_KEY); }; - if (!init_metric_id_allocator(paired_device_map, std::move(save_device_callback), - std::move(forget_device_callback))) { + if (!bluetooth::shim::InitMetricIdAllocator(paired_device_map, std::move(save_device_callback), + std::move(forget_device_callback))) { log::fatal("Failed to initialize MetricIdAllocator"); } // Add device_without_id for (auto& address : addresses_without_id) { - allocate_metric_id_from_metric_id_allocator(address); - save_metric_id_from_metric_id_allocator(address); + bluetooth::shim::AllocateIdFromMetricIdAllocator(address); + bluetooth::shim::SaveDeviceOnMetricIdAllocator(address); } } @@ -160,7 +161,7 @@ static future_t* clean_up(void) { "assert failed: bluetooth::shim::is_gd_stack_started_up()"); // GD storage module cleanup by itself std::unique_lock<std::recursive_mutex> lock(config_lock); - close_metric_id_allocator(); + bluetooth::shim::CloseMetricIdAllocator(); return future_new_immediate(FUTURE_SUCCESS); } diff --git a/system/btif/src/btif_dm.cc b/system/btif/src/btif_dm.cc index 96ed5848b1..44b876af4e 100644 --- a/system/btif/src/btif_dm.cc +++ b/system/btif/src/btif_dm.cc @@ -57,7 +57,6 @@ #include "btif_api.h" #include "btif_bqr.h" #include "btif_config.h" -#include "btif_metrics_logging.h" #include "btif_sdp.h" #include "btif_storage.h" #include "btif_util.h" @@ -72,6 +71,8 @@ #include "main/shim/entry.h" #include "main/shim/helpers.h" #include "main/shim/le_advertising_manager.h" +#include "main/shim/metric_id_api.h" +#include "main/shim/metrics_api.h" #include "main_thread.h" #include "metrics/bluetooth_event.h" #include "os/system_properties.h" @@ -582,11 +583,11 @@ static void bond_state_changed(bt_status_t status, const RawAddress& bd_addr, state, pairing_cb.state, pairing_cb.sdp_attempts); if (state == BT_BOND_STATE_NONE) { - forget_device_from_metric_id_allocator(bd_addr); + bluetooth::shim::ForgetDeviceFromMetricIdAllocator(bd_addr); btif_config_remove_device(bd_addr.ToString()); } else if (state == BT_BOND_STATE_BONDED) { - allocate_metric_id_from_metric_id_allocator(bd_addr); - if (!save_metric_id_from_metric_id_allocator(bd_addr)) { + bluetooth::shim::AllocateIdFromMetricIdAllocator(bd_addr); + if (!bluetooth::shim::SaveDeviceOnMetricIdAllocator(bd_addr)) { log::error("Fail to save metric id for device:{}", bd_addr); } } diff --git a/system/btif/src/btif_hf.cc b/system/btif/src/btif_hf.cc index 33fb900e07..c5dc2bca6a 100644 --- a/system/btif/src/btif_hf.cc +++ b/system/btif/src/btif_hf.cc @@ -51,7 +51,6 @@ #include "bta/include/utl.h" #include "bta_ag_swb_aptx.h" #include "btif/include/btif_common.h" -#include "btif/include/btif_metrics_logging.h" #include "btif/include/btif_profile_queue.h" #include "btif/include/btif_util.h" #include "btm_api_types.h" @@ -390,7 +389,7 @@ static void btif_hf_upstreams_evt(uint16_t event, char* p_param) { p_data->open.status, btif_hf_cb[idx].connected_bda, p_data->open.bd_addr); bt_hf_callbacks->ConnectionStateCallback(BTHF_CONNECTION_STATE_DISCONNECTED, &(p_data->open.bd_addr)); - log_counter_metrics_btif( + bluetooth::shim::CountCounterMetrics( android::bluetooth::CodePathCounterKeyEnum::HFP_COLLISON_AT_AG_OPEN, 1); } break; @@ -412,7 +411,7 @@ static void btif_hf_upstreams_evt(uint16_t event, char* p_param) { btif_hf_cb[idx].connected_bda, p_data->open.bd_addr); bt_hf_callbacks->ConnectionStateCallback(BTHF_CONNECTION_STATE_DISCONNECTED, &(btif_hf_cb[idx].connected_bda)); - log_counter_metrics_btif( + bluetooth::shim::CountCounterMetrics( android::bluetooth::CodePathCounterKeyEnum::HFP_COLLISON_AT_CONNECTING, 1); reset_control_block(&btif_hf_cb[idx]); btif_queue_advance(); @@ -472,7 +471,7 @@ static void btif_hf_upstreams_evt(uint16_t event, char* p_param) { bt_hf_callbacks->ConnectionStateCallback(btif_hf_cb[idx].state, &connected_bda); } - log_counter_metrics_btif( + bluetooth::shim::CountCounterMetrics( android::bluetooth::CodePathCounterKeyEnum::HFP_SELF_INITIATED_AG_FAILED, 1); btif_queue_advance(); if (btm_sec_is_a_bonded_dev(connected_bda)) { @@ -496,8 +495,8 @@ static void btif_hf_upstreams_evt(uint16_t event, char* p_param) { bt_hf_callbacks->ConnectionStateCallback(btif_hf_cb[idx].state, &connected_bda); if (failed_to_setup_slc) { log::error("failed to setup SLC for {}", connected_bda); - log_counter_metrics_btif(android::bluetooth::CodePathCounterKeyEnum::HFP_SLC_SETUP_FAILED, - 1); + bluetooth::shim::CountCounterMetrics( + android::bluetooth::CodePathCounterKeyEnum::HFP_SLC_SETUP_FAILED, 1); btif_queue_advance(); LogMetricHfpSlcFail(ToGdAddress(p_data->open.bd_addr)); DEVICE_IOT_CONFIG_ADDR_INT_ADD_ONE(btif_hf_cb[idx].connected_bda, diff --git a/system/btif/src/btif_hh.cc b/system/btif/src/btif_hh.cc index 7288abe98c..36ad3d148e 100644 --- a/system/btif/src/btif_hh.cc +++ b/system/btif/src/btif_hh.cc @@ -48,7 +48,6 @@ #include "btif/include/btif_common.h" #include "btif/include/btif_dm.h" #include "btif/include/btif_hd.h" -#include "btif/include/btif_metrics_logging.h" #include "btif/include/btif_profile_storage.h" #include "btif/include/btif_storage.h" #include "btif/include/btif_util.h" @@ -56,6 +55,7 @@ #include "include/hardware/bt_hh.h" #include "internal_include/bt_target.h" #include "main/shim/dumpsys.h" +#include "main/shim/metrics_api.h" #include "osi/include/alarm.h" #include "osi/include/allocator.h" #include "stack/include/bt_hdr.h" @@ -468,7 +468,7 @@ static void btif_hh_incoming_connection_timeout(void* data) { handle); } log::warn("Reject unexpected incoming HID Connection, device: {}", conn.link_spec); - log_counter_metrics_btif( + bluetooth::shim::CountCounterMetrics( android::bluetooth::CodePathCounterKeyEnum::HIDH_COUNT_INCOMING_CONNECTION_REJECTED, 1); btif_hh_device_t* p_dev = btif_hh_find_dev_by_link_spec(conn.link_spec); @@ -529,7 +529,7 @@ static bool hh_add_device(const tAclLinkSpec& link_spec, tBTA_HH_ATTR_MASK attr_ } log::error("Out of space to add device"); - log_counter_metrics_btif( + bluetooth::shim::CountCounterMetrics( android::bluetooth::CodePathCounterKeyEnum::HIDH_COUNT_MAX_ADDED_DEVICE_LIMIT_REACHED, 1); return false; } @@ -633,7 +633,7 @@ static void hh_open_handler(tBTA_HH_CONN& conn) { log::warn("Reject Incoming HID Connection, device: {}, state: {}", conn.link_spec, bthh_connection_state_text(dev_status)); - log_counter_metrics_btif( + bluetooth::shim::CountCounterMetrics( android::bluetooth::CodePathCounterKeyEnum::HIDH_COUNT_INCOMING_CONNECTION_REJECTED, 1); if (p_dev != nullptr) { @@ -910,9 +910,10 @@ static void hh_vc_unplug_handler(tBTA_HH_CBDATA& dev_status) { BTHH_STATE_UPDATE(p_dev->link_spec, p_dev->dev_status); if (!p_dev->local_vup) { - log_counter_metrics_btif(android::bluetooth::CodePathCounterKeyEnum:: - HIDH_COUNT_VIRTUAL_UNPLUG_REQUESTED_BY_REMOTE_DEVICE, - 1); + bluetooth::shim::CountCounterMetrics( + android::bluetooth::CodePathCounterKeyEnum:: + HIDH_COUNT_VIRTUAL_UNPLUG_REQUESTED_BY_REMOTE_DEVICE, + 1); } // Remove the HID device @@ -1193,9 +1194,10 @@ bt_status_t btif_hh_connect(const tAclLinkSpec& link_spec) { if (!p_dev && btif_hh_cb.device_num >= BTIF_HH_MAX_HID) { // No space for more HID device now. log::warn("Error, exceeded the maximum supported HID device number {}", BTIF_HH_MAX_HID); - log_counter_metrics_btif(android::bluetooth::CodePathCounterKeyEnum:: - HIDH_COUNT_CONNECT_REQ_WHEN_MAX_DEVICE_LIMIT_REACHED, - 1); + bluetooth::shim::CountCounterMetrics( + android::bluetooth::CodePathCounterKeyEnum:: + HIDH_COUNT_CONNECT_REQ_WHEN_MAX_DEVICE_LIMIT_REACHED, + 1); return BT_STATUS_NOMEM; } @@ -2030,7 +2032,7 @@ static bt_status_t get_report(RawAddress* bd_addr, tBLE_ADDR_TYPE addr_type, return BT_STATUS_DEVICE_NOT_FOUND; } else if (((int)reportType) <= BTA_HH_RPTT_RESRV || ((int)reportType) > BTA_HH_RPTT_FEATURE) { log::error("report type={} not supported", reportType); - log_counter_metrics_btif( + bluetooth::shim::CountCounterMetrics( android::bluetooth::CodePathCounterKeyEnum::HIDH_COUNT_WRONG_REPORT_TYPE, 1); return BT_STATUS_UNSUPPORTED; } else { @@ -2102,7 +2104,7 @@ static bt_status_t set_report(RawAddress* bd_addr, tBLE_ADDR_TYPE addr_type, return BT_STATUS_DEVICE_NOT_FOUND; } else if (((int)reportType) <= BTA_HH_RPTT_RESRV || ((int)reportType) > BTA_HH_RPTT_FEATURE) { log::error("report type={} not supported", reportType); - log_counter_metrics_btif( + bluetooth::shim::CountCounterMetrics( android::bluetooth::CodePathCounterKeyEnum::HIDH_COUNT_WRONG_REPORT_TYPE, 1); return BT_STATUS_UNSUPPORTED; } else { diff --git a/system/btif/src/btif_metrics_logging.cc b/system/btif/src/btif_metrics_logging.cc deleted file mode 100644 index 40f2fed315..0000000000 --- a/system/btif/src/btif_metrics_logging.cc +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2021 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. - */ - -#include "btif/include/btif_metrics_logging.h" - -#include <frameworks/proto_logging/stats/enums/bluetooth/enums.pb.h> -#include <frameworks/proto_logging/stats/enums/bluetooth/hci/enums.pb.h> - -#include "main/shim/metrics_api.h" -#include "types/raw_address.h" - -void log_a2dp_audio_underrun_event(const RawAddress& address, uint64_t encoding_interval_millis, - int num_missing_pcm_bytes) { - bluetooth::shim::LogMetricA2dpAudioUnderrunEvent(address, encoding_interval_millis, - num_missing_pcm_bytes); -} - -void log_a2dp_audio_overrun_event(const RawAddress& address, uint64_t encoding_interval_millis, - int num_dropped_buffers, int num_dropped_encoded_frames, - int num_dropped_encoded_bytes) { - bluetooth::shim::LogMetricA2dpAudioOverrunEvent(address, encoding_interval_millis, - num_dropped_buffers, num_dropped_encoded_frames, - num_dropped_encoded_bytes); -} - -void log_a2dp_playback_event(const RawAddress& address, int playback_state, int audio_coding_mode) { - bluetooth::shim::LogMetricA2dpPlaybackEvent(address, playback_state, audio_coding_mode); -} - -void log_a2dp_session_metrics_event(const RawAddress& address, int64_t audio_duration_ms, - int media_timer_min_ms, int media_timer_max_ms, - int media_timer_avg_ms, int total_scheduling_count, - int buffer_overruns_max_count, int buffer_overruns_total, - float buffer_underruns_average, int buffer_underruns_count, - int64_t codec_index, bool is_a2dp_offload) { - bluetooth::shim::LogMetricA2dpSessionMetricsEvent( - address, audio_duration_ms, media_timer_min_ms, media_timer_max_ms, media_timer_avg_ms, - total_scheduling_count, buffer_overruns_max_count, buffer_overruns_total, - buffer_underruns_average, buffer_underruns_count, codec_index, is_a2dp_offload); -} - -void log_read_rssi_result(const RawAddress& address, uint16_t handle, uint32_t cmd_status, - int8_t rssi) { - bluetooth::shim::LogMetricReadRssiResult(address, handle, cmd_status, rssi); -} - -void log_read_failed_contact_counter_result(const RawAddress& address, uint16_t handle, - uint32_t cmd_status, int32_t failed_contact_counter) { - bluetooth::shim::LogMetricReadFailedContactCounterResult(address, handle, cmd_status, - failed_contact_counter); -} - -void log_read_tx_power_level_result(const RawAddress& address, uint16_t handle, uint32_t cmd_status, - int32_t transmit_power_level) { - bluetooth::shim::LogMetricReadTxPowerLevelResult(address, handle, cmd_status, - transmit_power_level); -} - -void log_socket_connection_state(const RawAddress& address, int port, int type, - android::bluetooth::SocketConnectionstateEnum connection_state, - int64_t tx_bytes, int64_t rx_bytes, int uid, int server_port, - android::bluetooth::SocketRoleEnum socket_role, - uint64_t connection_duration_ms, - android::bluetooth::SocketErrorEnum error_code, - bool is_hardware_offload) { - bluetooth::shim::LogMetricSocketConnectionState( - address, port, type, connection_state, tx_bytes, rx_bytes, uid, server_port, socket_role, - connection_duration_ms, error_code, is_hardware_offload); -} - -void log_counter_metrics_btif(android::bluetooth::CodePathCounterKeyEnum key, int64_t value) { - bluetooth::shim::CountCounterMetrics(key, value); -} - -bool init_metric_id_allocator(const std::unordered_map<RawAddress, int>& paired_device_map, - bluetooth::shim::CallbackLegacy save_device_callback, - bluetooth::shim::CallbackLegacy forget_device_callback) { - return bluetooth::shim::InitMetricIdAllocator(paired_device_map, std::move(save_device_callback), - std::move(forget_device_callback)); -} - -bool close_metric_id_allocator() { return bluetooth::shim::CloseMetricIdAllocator(); } - -int allocate_metric_id_from_metric_id_allocator(const RawAddress& address) { - return bluetooth::shim::AllocateIdFromMetricIdAllocator(address); -} - -int save_metric_id_from_metric_id_allocator(const RawAddress& address) { - return bluetooth::shim::SaveDeviceOnMetricIdAllocator(address); -} - -void forget_device_from_metric_id_allocator(const RawAddress& address) { - bluetooth::shim::ForgetDeviceFromMetricIdAllocator(address); -} - -bool is_valid_id_from_metric_id_allocator(const int id) { - return bluetooth::shim::IsValidIdFromMetricIdAllocator(id); -} diff --git a/system/btif/src/btif_sock_logging.cc b/system/btif/src/btif_sock_logging.cc index 111e52002b..8847daa7f1 100644 --- a/system/btif/src/btif_sock_logging.cc +++ b/system/btif/src/btif_sock_logging.cc @@ -23,9 +23,9 @@ #include <atomic> -#include "btif/include/btif_metrics_logging.h" #include "btif/include/btif_sock.h" #include "common/time_util.h" +#include "main/shim/metrics_api.h" #include "types/raw_address.h" #define SOCK_LOGGER_SIZE_MAX 16 @@ -79,7 +79,7 @@ void btif_sock_connection_logger(const RawAddress& address, int port, int type, } clock_gettime(CLOCK_REALTIME, &connection_logger[index].timestamp); - log_socket_connection_state( + bluetooth::shim::LogMetricSocketConnectionState( address, port, type, toConnectionStateEnum(state), tx_bytes, rx_bytes, uid, server_port, toSocketRoleEnum(role), getConnectionDuration(connection_start_time_ms), toSocketErrorEnum(error_code), data_path == BTSOCK_DATA_PATH_HARDWARE_OFFLOAD); diff --git a/system/btif/src/btif_sock_rfc.cc b/system/btif/src/btif_sock_rfc.cc index 4c75b0f355..1ea4bf9981 100644 --- a/system/btif/src/btif_sock_rfc.cc +++ b/system/btif/src/btif_sock_rfc.cc @@ -33,7 +33,6 @@ #include "bta/include/bta_jv_co.h" #include "bta/include/bta_rfcomm_metrics.h" #include "bta/include/bta_rfcomm_scn.h" -#include "btif/include/btif_metrics_logging.h" #include "btif/include/btif_sock.h" #include "btif/include/btif_sock_l2cap.h" #include "btif/include/btif_sock_logging.h" @@ -45,6 +44,7 @@ #include "include/hardware/bt_sock.h" #include "lpp/lpp_offload_interface.h" #include "main/shim/entry.h" +#include "main/shim/metrics_api.h" #include "osi/include/allocator.h" #include "osi/include/compat.h" #include "osi/include/list.h" @@ -909,12 +909,12 @@ static void on_rfc_close(tBTA_JV_RFCOMM_CLOSE* /* p_close */, uint32_t id) { log::warn("RFCOMM slot with id {} not found.", id); return; } - log_socket_connection_state(slot->addr, slot->id, BTSOCK_RFCOMM, - android::bluetooth::SOCKET_CONNECTION_STATE_DISCONNECTING, 0, 0, - slot->app_uid, slot->scn, - slot->f.server ? android::bluetooth::SOCKET_ROLE_LISTEN - : android::bluetooth::SOCKET_ROLE_CONNECTION, - 0, android::bluetooth::SOCKET_ERROR_NONE, slot->data_path); + bluetooth::shim::LogMetricSocketConnectionState( + slot->addr, slot->id, BTSOCK_RFCOMM, + android::bluetooth::SOCKET_CONNECTION_STATE_DISCONNECTING, 0, 0, slot->app_uid, slot->scn, + slot->f.server ? android::bluetooth::SOCKET_ROLE_LISTEN + : android::bluetooth::SOCKET_ROLE_CONNECTION, + 0, android::bluetooth::SOCKET_ERROR_NONE, slot->data_path); cleanup_rfc_slot(slot, BTSOCK_ERROR_NONE); } diff --git a/system/gd/hci/distance_measurement_manager_test.cc b/system/gd/hci/distance_measurement_manager_test.cc index 05d2e82ce2..8679ec27e3 100644 --- a/system/gd/hci/distance_measurement_manager_test.cc +++ b/system/gd/hci/distance_measurement_manager_test.cc @@ -80,7 +80,7 @@ struct CsReadCapabilitiesCompleteEvent { CsOptionalNadmSoundingCapability nadm_sounding_capability = { /*normalized_attack_detector_metric=*/1}; CsOptionalNadmRandomCapability nadm_random_capability = {/*normalized_attack_detector_metric=*/1}; - CsOptionalCsSyncPhysSupported cs_sync_phys_supported = {/*le_2m_phy=*/1}; + CsOptionalCsSyncPhysSupported cs_sync_phys_supported = {/*le_2m_phy=*/1, /*le_2m_2bt_phy=*/0}; CsOptionalSubfeaturesSupported subfeatures_supported = {/*no_frequency_actuation_error=*/1, /*channel_selection_algorithm=*/1, /*phase_based_ranging=*/1}; diff --git a/system/pdl/hci/hci_packets.pdl b/system/pdl/hci/hci_packets.pdl index fcdd255b99..838b1fa586 100644 --- a/system/pdl/hci/hci_packets.pdl +++ b/system/pdl/hci/hci_packets.pdl @@ -4949,7 +4949,8 @@ struct CsOptionalNadmRandomCapability { struct CsOptionalCsSyncPhysSupported { le_2m_phy : 1, - _reserved_ : 7, + le_2m_2bt_phy : 1, + _reserved_ : 6, } struct CsOptionalSubfeaturesSupported { @@ -5151,6 +5152,7 @@ enum CsConfigRttType : 8 { enum CsSyncPhy : 8 { LE_1M_PHY = 0x01, LE_2M_PHY = 0x02, + LE_2M_2BT_PHY = 0x03, } enum CsChannelSelectionType : 8 { diff --git a/system/stack/rfcomm/port_api.cc b/system/stack/rfcomm/port_api.cc index a78f3ea890..6ab7cdccea 100644 --- a/system/stack/rfcomm/port_api.cc +++ b/system/stack/rfcomm/port_api.cc @@ -1229,7 +1229,9 @@ int PORT_GetChannelInfo(uint16_t handle, uint16_t* local_mtu, uint16_t* remote_m return PORT_NOT_OPENED; } - if (p_port->line_status) { + if (p_port->rfc.p_mcb == nullptr || p_port->line_status) { + log::warn("PORT_LINE_ERR - p_port->rfc.p_mcb == nullptr:{} p_port->line_status:{}", + (p_port->rfc.p_mcb == nullptr) ? "T" : "F", p_port->line_status); return PORT_LINE_ERR; } diff --git a/system/stack/rfcomm/rfc_l2cap_if.cc b/system/stack/rfcomm/rfc_l2cap_if.cc index 5b7fc00185..10826d235a 100644 --- a/system/stack/rfcomm/rfc_l2cap_if.cc +++ b/system/stack/rfcomm/rfc_l2cap_if.cc @@ -91,28 +91,26 @@ void rfcomm_l2cap_if_init(void) { void RFCOMM_ConnectInd(const RawAddress& bd_addr, uint16_t lcid, uint16_t /* psm */, uint8_t id) { tRFC_MCB* p_mcb = rfc_alloc_multiplexer_channel(bd_addr, false); - if ((p_mcb) && (p_mcb->state != RFC_MX_STATE_IDLE)) { - /* if this is collision case */ - if ((p_mcb->is_initiator) && (p_mcb->state == RFC_MX_STATE_WAIT_CONN_CNF)) { - p_mcb->pending_lcid = lcid; - - /* wait random timeout (2 - 12) to resolve collision */ - /* if peer gives up then local device rejects incoming connection and - * continues as initiator */ - /* if timeout, local device disconnects outgoing connection and continues - * as acceptor */ - log::verbose( - "RFCOMM_ConnectInd start timer for collision, initiator's " - "LCID(0x{:x}), acceptor's LCID(0x{:x})", - p_mcb->lcid, p_mcb->pending_lcid); - - rfc_timer_start(p_mcb, (uint16_t)(bluetooth::common::time_get_os_boottime_ms() % 10 + 2)); - return; - } else { - /* we cannot accept connection request from peer at this state */ - /* don't update lcid */ - p_mcb = nullptr; - } + if (p_mcb != nullptr && p_mcb->is_initiator && p_mcb->state == RFC_MX_STATE_WAIT_CONN_CNF) { + p_mcb->pending_lcid = lcid; + + /* wait random timeout (2 - 12) to resolve collision */ + /* if peer gives up then local device rejects incoming connection and + * continues as initiator */ + /* if timeout, local device disconnects outgoing connection and continues + * as acceptor */ + log::verbose( + "RFCOMM_ConnectInd start timer for collision, initiator's " + "LCID(0x{:x}), acceptor's LCID(0x{:x})", + p_mcb->lcid, p_mcb->pending_lcid); + + rfc_timer_start(p_mcb, (uint16_t)(bluetooth::common::time_get_os_boottime_ms() % 10 + 2)); + return; + } + if (p_mcb != nullptr && p_mcb->is_initiator && p_mcb->state != RFC_MX_STATE_IDLE) { + /* we cannot accept connection request from peer at this state */ + /* don't update lcid */ + p_mcb = nullptr; } else { /* store mcb even if null */ rfc_save_lcid_mcb(p_mcb, lcid); @@ -141,7 +139,7 @@ void RFCOMM_ConnectInd(const RawAddress& bd_addr, uint16_t lcid, uint16_t /* psm void RFCOMM_ConnectCnf(uint16_t lcid, tL2CAP_CONN result) { tRFC_MCB* p_mcb = rfc_find_lcid_mcb(lcid); - if (!p_mcb) { + if (p_mcb == nullptr) { log::error("RFCOMM_ConnectCnf LCID:0x{:x}", lcid); return; } @@ -188,7 +186,7 @@ void RFCOMM_ConfigInd(uint16_t lcid, tL2CAP_CFG_INFO* p_cfg) { tRFC_MCB* p_mcb = rfc_find_lcid_mcb(lcid); - if (!p_mcb) { + if (p_mcb == nullptr) { log::error("RFCOMM_ConfigInd LCID:0x{:x}", lcid); for (auto& [cid, mcb] : rfc_lcid_mcb) { if (mcb != nullptr && mcb->pending_lcid == lcid) { @@ -218,7 +216,7 @@ void RFCOMM_ConfigCnf(uint16_t lcid, uint16_t /* initiator */, tL2CAP_CFG_INFO* tRFC_MCB* p_mcb = rfc_find_lcid_mcb(lcid); - if (!p_mcb) { + if (p_mcb == nullptr) { log::error("RFCOMM_ConfigCnf no MCB LCID:0x{:x}", lcid); return; } @@ -237,7 +235,7 @@ void RFCOMM_ConfigCnf(uint16_t lcid, uint16_t /* initiator */, tL2CAP_CFG_INFO* void RFCOMM_DisconnectInd(uint16_t lcid, bool is_conf_needed) { log::verbose("lcid:0x{:x}, is_conf_needed:{}", lcid, is_conf_needed); tRFC_MCB* p_mcb = rfc_find_lcid_mcb(lcid); - if (!p_mcb) { + if (p_mcb == nullptr) { log::warn("no mcb for lcid 0x{:x}", lcid); return; } @@ -257,7 +255,7 @@ void RFCOMM_DisconnectInd(uint16_t lcid, bool is_conf_needed) { void RFCOMM_BufDataInd(uint16_t lcid, BT_HDR* p_buf) { tRFC_MCB* p_mcb = rfc_find_lcid_mcb(lcid); - if (!p_mcb) { + if (p_mcb == nullptr) { log::warn("Cannot find RFCOMM multiplexer for lcid 0x{:x}", lcid); osi_free(p_buf); return; @@ -351,7 +349,7 @@ void RFCOMM_BufDataInd(uint16_t lcid, BT_HDR* p_buf) { void RFCOMM_CongestionStatusInd(uint16_t lcid, bool is_congested) { tRFC_MCB* p_mcb = rfc_find_lcid_mcb(lcid); - if (!p_mcb) { + if (p_mcb == nullptr) { log::error("RFCOMM_CongestionStatusInd dropped LCID:0x{:x}", lcid); return; } else { diff --git a/system/test/README.md b/system/test/README.md deleted file mode 100644 index 1f43e952ef..0000000000 --- a/system/test/README.md +++ /dev/null @@ -1,81 +0,0 @@ -# Fluoride Bluetooth Tests - -This document refers to the tests in the packages/modules/Bluetooth/system/test directory. - -The tests are designed to be run when the Android runtime is not running. From a terminal, run: - -## Before you run tests -```sh -adb shell stop -``` - -## After you're done -```sh -adb shell start -``` - -## Running tests -Then see what options the test script provides: - -```sh -./run_unit_tests.sh --help -``` - -But for the impatient, run specific groups of tests like this: - -```sh -./run_unit_tests.sh net_test_bluetooth -``` - -a single test: - -```sh -./run_unit_tests.sh net_test_bluetooth.BluetoothTest.AdapterRepeatedEnableDisable -``` - -## Sample Output - -packages/modules/Bluetooth/system/test$ ./run_unit_tests.sh net_test_bluetooth ---- net_test_bluetooth --- -pushing... -/tbd/aosp-master/out/target/product/bullhead/data/nativetest/n...st_bluetooth: 1 file pushed. 9.2 MB/s (211832 bytes in 0.022s) -running... - -Running main() from gtest_main.cc -[==========] Running 11 tests from 2 test cases. -[----------] Global test environment set-up. -[----------] 6 tests from BluetoothTest -[ RUN ] BluetoothTest.AdapterEnableDisable -[ OK ] BluetoothTest.AdapterEnableDisable (2538 ms) -[ RUN ] BluetoothTest.AdapterRepeatedEnableDisable -[ OK ] BluetoothTest.AdapterRepeatedEnableDisable (11384 ms) -[ RUN ] BluetoothTest.AdapterSetGetName -[ OK ] BluetoothTest.AdapterSetGetName (2378 ms) -[ RUN ] BluetoothTest.AdapterStartDiscovery -[ OK ] BluetoothTest.AdapterStartDiscovery (2397 ms) -[ RUN ] BluetoothTest.AdapterCancelDiscovery -[ OK ] BluetoothTest.AdapterCancelDiscovery (2401 ms) -[ RUN ] BluetoothTest.AdapterDisableDuringBonding -[ OK ] BluetoothTest.AdapterDisableDuringBonding (11689 ms) -[----------] 6 tests from BluetoothTest (32789 ms total) - -[----------] 5 tests from GattTest -[ RUN ] GattTest.GattClientRegister -[ OK ] GattTest.GattClientRegister (2370 ms) -[ RUN ] GattTest.GattClientScanRemoteDevice -[ OK ] GattTest.GattClientScanRemoteDevice (2273 ms) -[ RUN ] GattTest.GattClientAdvertise -[ OK ] GattTest.GattClientAdvertise (2236 ms) -[ RUN ] GattTest.GattServerRegister -[ OK ] GattTest.GattServerRegister (2391 ms) -[ RUN ] GattTest.GattServerBuild -[ OK ] GattTest.GattServerBuild (2435 ms) -[----------] 5 tests from GattTest (11706 ms total) - -[----------] Global test environment tear-down -[==========] 11 tests from 2 test cases ran. (44495 ms total) -[ PASSED ] 11 tests. - -## Troubleshooting: Your phone is bricked! -Probably not. See [After you're done](#After-you're-done) - |