NordicSemiconductor / Android-BLE-Library

A library that makes working with Bluetooth LE on Android a pleasure. Seriously.
BSD 3-Clause "New" or "Revised" License
2.05k stars 420 forks source link

Need BLUETOOTH PRIVILEGED permission - Android 13 #507

Closed archie94 closed 1 year ago

archie94 commented 1 year ago

On certain user devices (all Android 13) we are facing the following crash.

Fatal Exception: java.lang.SecurityException: Need BLUETOOTH PRIVILEGED permission: Neither user 10145 nor current process has android.permission.BLUETOOTH_PRIVILEGED.
       at android.app.ContextImpl.enforce(ContextImpl.java:2240)
       at android.app.ContextImpl.enforceCallingOrSelfPermission(ContextImpl.java:2268)
       at android.content.ContextWrapper.enforceCallingOrSelfPermission(ContextWrapper.java:948)
       at com.android.bluetooth.Utils.enforceBluetoothPrivilegedPermission(Utils.java:388)
       at com.android.bluetooth.gatt.GattService.permissionCheck(GattService.java:513)
       at com.android.bluetooth.gatt.GattService.readCharacteristic(GattService.java:3789)
       at com.android.bluetooth.gatt.GattService$BluetoothGattBinder.readCharacteristic(GattService.java:987)
       at com.android.bluetooth.gatt.GattService$BluetoothGattBinder.readCharacteristic(GattService.java:975)
       at android.bluetooth.IBluetoothGatt$Stub.onTransact(IBluetoothGatt.java:970)
       at android.os.Binder.execTransactInternal(Binder.java:1285)
       at android.os.Binder.execTransact(Binder.java:1244)

Something related I could find on SF but we are not enabling notification on any restricted characteristics. Is there any way the library can shed more info on these crashes?

LuoPeiQin commented 1 year ago

I also encountered the same problem.

philips77 commented 1 year ago

Hello, what characteristic you're trying to read? Are you sure you have the correct UUID and reference?

archie94 commented 1 year ago

Hello!

Our peripheral has few standard services like 0000180a-0000-1000-8000-00805f9b34fb and 0000181e-0000-1000-8000-00805f9b34fb but the rest are our custom services.

Hex code are 86f65000-f706-58a0-95b2-1fb9261e4dc7 / 86f66000-f706-58a0-95b2-1fb9261e4dc7 / 86f61000-f706-58a0-95b2-1fb9261e4dc7

This crash occurs on android 13 devices only so not sure if this has to do with wrong implementation on our end.

philips77 commented 1 year ago

Did you try clearing caches on the affected phone by restarting Bluetooth or in nRF Connect?

archie94 commented 1 year ago

Unfortunately this we haven't found in our test devices. All on remote user devices. Anything else you think we can try?

corentin-c commented 1 year ago

I think I remember having this exception when the bluetooth is disabled on some devices. Did you make sure bluetooth is enabled before doing those calls ?

archie94 commented 1 year ago

Yes. Saw the same on a stackoverflow thread. We make sure bluetooth is enabled before connecting to a peripheral.

NoviaWu123 commented 1 year ago

Unfortunately this we haven't found in our test devices. All on remote user devices. Anything else you think we can try?

I also encountered this problem, but still couldn't find a solution.

  1. You can try connecting to an HID device and remember its connId (connection ID).

  2. Disconnect the HID device.

  3. Connect to a new Bluetooth device. If the connId is the same, this bug should be triggered.

plotczyktest commented 1 year ago

We also encounter this issue. I think that this is somehow Android 13 related as all those errors occur on this particular version. The problem may be that Android i caching characteristics for particular BLE devices. Like NoviaWu123 mentioned if for some reason we first make a connection with device that uses forbidden characteristics and later connect with second device not using any forbidden characteristics it may happen that Android will share this connection ID and aggregate characteristics from both of those devices (not sure how it may happen) GattService.java

The only solution I can think of is to try refreshing deviceChache (refreshDeviceCache()) and then reconnecting. However we would need a trigger for it like catching this particular exception java.lang.SecurityException This exception however can only be caught inside Android-BLE-Library

So my suggestion would be to add a try catch inside BleManagerHandler#internalReadCharacteristic() and possibly add new FailCallback reason that will be notified to Android App (without crashing the whole app) so that devs can handle this exception them self like for example calling refreshDeviceCache() and trying to reconnect

nadrolinux commented 1 year ago

I also see this issue on Pixel 6 with Android 13, however it starts today, yesterday all was fine. After phone reboot all starts working again. I think it may be related to connected smartband (Xiaomi Band 6) to Pixel 6 , because when smartband is disconnected all works fine. I also see that when smartband is connected it auto connect to my gatt server dedicated to my app and I'm not sure how can I filter it.

elongpaoxiao commented 1 year ago

The result of my testing here is that if I use a Google Android 13 phone to connect, the previous connected device contains a special uuid defined by android, then I disconnect and connect to the next device that does not contain a special uuid, this problem will occur.

public class GattService extends ProfileService {
   private static final boolean DBG = GattServiceConfig.DBG;
   private static final boolean VDBG = GattServiceConfig.VDBG;
   private static final String TAG = GattServiceConfig.TAG_PREFIX + "GattService";
   private static final String UUID_SUFFIX = "-0000-1000-8000-00805f9b34fb";
   private static final String UUID_ZERO_PAD = "00000000";
    
   static final int SCAN_FILTER_ENABLED = 1;
   static final int SCAN_FILTER_MODIFIED = 2;
    
   private static final int MAC_ADDRESS_LENGTH = 6;
   // Batch scan related constants.
   private static final int TRUNCATED_RESULT_SIZE = 11;
   private static final int TIME_STAMP_LENGTH = 2;
    
   /**
   * The default floor value for LE batch scan report delays greater than 0
   */
   private static final long DEFAULT_REPORT_DELAY_FLOOR = 5000;
    
   // onFoundLost related constants
   private static final int ADVT_STATE_ONFOUND = 0;
   private static final int ADVT_STATE_ONLOST = 1;
    
   private static final int ET_LEGACY_MASK = 0x10;
    
   private static final UUID HID_SERVICE_UUID =
      UUID.fromString("00001812-0000-1000-8000-00805F9B34FB");
    
   private static final UUID[] HID_UUIDS = {
      UUID.fromString("00002A4A-0000-1000-8000-00805F9B34FB"),
      UUID.fromString("00002A4B-0000-1000-8000-00805F9B34FB"),
      UUID.fromString("00002A4C-0000-1000-8000-00805F9B34FB"),
      UUID.fromString("00002A4D-0000-1000-8000-00805F9B34FB")
   };
    
   private static final UUID ANDROID_TV_REMOTE_SERVICE_UUID =
      UUID.fromString("AB5E0001-5A21-4F05-BC7D-AF01F617B664");
    
   private static final UUID FIDO_SERVICE_UUID =
      UUID.fromString("0000FFFD-0000-1000-8000-00805F9B34FB"); // U2F
    
   private static final UUID[] LE_AUDIO_SERVICE_UUIDS = {
      UUID.fromString("00001844-0000-1000-8000-00805F9B34FB"), // VCS
      UUID.fromString("00001845-0000-1000-8000-00805F9B34FB"), // VOCS
      UUID.fromString("00001843-0000-1000-8000-00805F9B34FB"), // AICS
      UUID.fromString("00001850-0000-1000-8000-00805F9B34FB"), // PACS
      UUID.fromString("0000184E-0000-1000-8000-00805F9B34FB"), // ASCS
      UUID.fromString("0000184F-0000-1000-8000-00805F9B34FB"), // BASS
   };
archie94 commented 1 year ago

Hi @philips77 Any suggestions how to handle this issue?

archie94 commented 1 year ago

Others are you able to circumvent the problem?

plotczyktest commented 1 year ago

Looks like toggling Bluetooth helps to resolve this issue. After reanabling Bluetooth looks like device cache is somehow cleared and forbidden characteristics are removed from services the real appliance is providing (tested on Pixel 6)

However we still get this crash and cannot catch it outside of the "Android BLE library" Can we ask for catching those inside of the lib and calling FailCallback with new status REASON? int REASON_BLUETOOTH_PERMISSION_ PRIVILEGED = -200; or smth like that?

AbdElrahman-Rafaat-Amer commented 1 year ago

I think it may happen because you trying to use the Bluetooth and it is turned off. This is the case I faced and have the same issue.

plotczyktest commented 1 year ago

We do not start Bluetooth communication when Bluetooth is Off :). I only mentioned that restarting Bluetooth on the phone solves this issue. But crash still occurs.

philips77 commented 1 year ago

I'll see what I can do.

archie94 commented 11 months ago

This crash seems to occur on 2.7.2 release also!

archie94 commented 9 months ago

Hello @philips77 any idea on this?

This is the crashlog

Fatal Exception: java.lang.SecurityException: Need BLUETOOTH PRIVILEGED permission: Neither user 10412 nor current process has android.permission.BLUETOOTH_PRIVILEGED.
       at android.app.ContextImpl.enforce(ContextImpl.java:2332)
       at android.app.ContextImpl.enforceCallingOrSelfPermission(ContextImpl.java:2360)
       at android.content.ContextWrapper.enforceCallingOrSelfPermission(ContextWrapper.java:982)
       at android.content.ContextWrapper.enforceCallingOrSelfPermission(ContextWrapper.java:982)
       at com.android.bluetooth.Utils.enforceBluetoothPrivilegedPermission(Utils.java:477)
       at com.android.bluetooth.gatt.GattService.permissionCheck(GattService.java:474)
       at com.android.bluetooth.gatt.GattService.registerForNotification(GattService.java:4050)
       at com.android.bluetooth.gatt.GattService$BluetoothGattBinder.registerForNotification(GattService.java:1119)
       at com.android.bluetooth.gatt.GattService$BluetoothGattBinder.registerForNotification(GattService.java:1107)
       at android.bluetooth.IBluetoothGatt$Stub.onTransact(IBluetoothGatt.java:1088)
       at android.os.Binder.execTransactInternal(Binder.java:1363)
       at android.os.Binder.execTransact(Binder.java:1304)

@LuoPeiQin @plotczyktest @elongpaoxiao @nadrolinux @NoviaWu123 anyone still facing this issue?

philips77 commented 9 months ago

What characteristic are you trying enable notifications on? Is it any of those from here: https://github.com/NordicSemiconductor/Android-BLE-Library/issues/507#issuecomment-1706118207 ? Are you using version 2.7.3? I can't see any library method in your stack trace.

archie94 commented 9 months ago

Characteristics are same as i mentioned here. We are on 2.7.2 I see 2.7.3 has https://github.com/NordicSemiconductor/Android-BLE-Library/pull/545 which may fix the issue. Will check. Thanks!

archie94 commented 8 months ago

Although frequency has reduced a bit but the problem still remains.

have created a new issue here: https://issuetracker.google.com/issues/330663537 earlier one was closed for inactivity here: https://issuetracker.google.com/issues/304893289

archie94 commented 8 months ago

I have sent a PR for handling this issue. @philips77 please review once you get time.

j0bro commented 6 months ago

Although frequency has reduced a bit but the problem still remains.

have created a new issue here: issuetracker.google.com/issues/330663537 earlier one was closed for inactivity here: issuetracker.google.com/issues/304893289

Great to see, and thanks for re-reporting. Google admits it's on their side and a fix is planned for rollout to the field they say in the new issue.

kle-wang commented 3 months ago

Although google admits and repair in android 15 beta3,most of user are not keep latest android version. How can we do?I just notice catch error,but nothing to do. May be refresh gatt cache?