Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Race condition in HidPeripheral.addService #11

Open
dbw9580 opened this issue Jan 16, 2019 · 0 comments
Open

Race condition in HidPeripheral.addService #11

dbw9580 opened this issue Jan 16, 2019 · 0 comments

Comments

@dbw9580
Copy link

dbw9580 commented Jan 16, 2019

According to Android doc BluetoothGattServer.addService:

The BluetoothGattServerCallback.onServiceAdded(int, BluetoothGattService) callback will indicate whether this service has been added successfully. Do not add another service before this callback.

The current codes in HidPeripheral.java break this promise and add several services in a row
without proper precautions. This results in race condition and failure adding services. The errors from logcat:

2019-01-16 15:21:18.859 26268-26268/me.dbw9580.apps.BridgeTooth D/BluetoothGattServer: registerCallback()
2019-01-16 15:21:18.859 26268-26268/me.dbw9580.apps.BridgeTooth D/BluetoothGattServer: registerCallback() - UUID=9f9ae403-ef94-4cfb-9925-4410ba150dff
2019-01-16 15:21:18.861 26268-26281/me.dbw9580.apps.BridgeTooth D/BluetoothGattServer: onServerRegistered() - status=0 serverIf=5
2019-01-16 15:21:18.861 26268-26268/me.dbw9580.apps.BridgeTooth D/BluetoothGattServer: addService() - service: 00001812-0000-1000-8000-00805f9b34fb
2019-01-16 15:21:18.869 26268-26268/me.dbw9580.apps.BridgeTooth D/HidPeripheral: Service: 00001812-0000-1000-8000-00805f9b34fb added.
2019-01-16 15:21:18.869 26268-26268/me.dbw9580.apps.BridgeTooth D/BluetoothGattServer: addService() - service: 0000180a-0000-1000-8000-00805f9b34fb
2019-01-16 15:21:18.871 26268-26281/me.dbw9580.apps.BridgeTooth D/BluetoothGattServer: onServiceAdded() - handle=40 uuid=00001812-0000-1000-8000-00805f9b34fb status=0
2019-01-16 15:21:18.871 26268-26268/me.dbw9580.apps.BridgeTooth D/HidPeripheral: Service: 0000180a-0000-1000-8000-00805f9b34fb added.
2019-01-16 15:21:18.871 26268-26268/me.dbw9580.apps.BridgeTooth D/BluetoothGattServer: addService() - service: 0000180f-0000-1000-8000-00805f9b34fb
2019-01-16 15:21:18.872 26268-26281/me.dbw9580.apps.BridgeTooth W/Binder: Caught a RuntimeException from the binder stub implementation.
    java.lang.IndexOutOfBoundsException: Index: 3, Size: 3
        at java.util.ArrayList.get(ArrayList.java:437)
        at android.bluetooth.BluetoothGattServer$1.onServiceAdded(BluetoothGattServer.java:121)
        at android.bluetooth.IBluetoothGattServerCallback$Stub.onTransact(IBluetoothGattServerCallback.java:85)
        at android.os.Binder.execTransact(Binder.java:674)
2019-01-16 15:21:18.872 26268-26268/me.dbw9580.apps.BridgeTooth D/HidPeripheral: Service: 0000180f-0000-1000-8000-00805f9b34fb added.
2019-01-16 15:21:18.874 26268-26281/me.dbw9580.apps.BridgeTooth D/BluetoothGattServer: onServiceAdded() - handle=56 uuid=0000180a-0000-1000-8000-00805f9b34fb status=0
2019-01-16 15:21:18.874 26268-26268/me.dbw9580.apps.BridgeTooth D/BluetoothKeyboardService: onStartCommand: Intent { cmp=me.dbw9580.apps.BridgeTooth/.BluetoothKeyboardService }
2019-01-16 15:21:18.874 26268-29450/me.dbw9580.apps.BridgeTooth D/BluetoothKeyboardService: received intent: null
2019-01-16 15:21:18.875 26268-26281/me.dbw9580.apps.BridgeTooth W/Binder: Caught a RuntimeException from the binder stub implementation.
    java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
        at java.util.ArrayList.get(ArrayList.java:437)
        at android.bluetooth.BluetoothGattServer$1.onServiceAdded(BluetoothGattServer.java:121)
        at android.bluetooth.IBluetoothGattServerCallback$Stub.onTransact(IBluetoothGattServerCallback.java:85)
        at android.os.Binder.execTransact(Binder.java:674)
2019-01-16 15:21:18.877 26268-26268/me.dbw9580.apps.BridgeTooth W/Notification: Use of stream types is deprecated for operations other than volume control
2019-01-16 15:21:18.877 26268-26268/me.dbw9580.apps.BridgeTooth W/Notification: See the documentation of setSound() for what to use instead with android.media.AudioAttributes to qualify your playback use case
2019-01-16 15:21:18.881 26268-26281/me.dbw9580.apps.BridgeTooth D/BluetoothGattServer: onServiceAdded() - handle=63 uuid=0000180f-0000-1000-8000-00805f9b34fb status=0
2019-01-16 15:21:18.889 26268-26268/me.dbw9580.apps.BridgeTooth D/HidPeripheral: advertiseData: AdvertiseData [mServiceUuids=[0000180a-0000-1000-8000-00805f9b34fb, 00001812-0000-1000-8000-00805f9b34fb, 0000180f-0000-1000-8000-00805f9b34fb], mManufacturerSpecificData={}, mServiceData={}, mIncludeTxPowerLevel=false, mIncludeDeviceName=true], scanResult: AdvertiseData [mServiceUuids=[0000180a-0000-1000-8000-00805f9b34fb, 00001812-0000-1000-8000-00805f9b34fb, 0000180f-0000-1000-8000-00805f9b34fb], mManufacturerSpecificData={}, mServiceData={}, mIncludeTxPowerLevel=false, mIncludeDeviceName=false]
2019-01-16 15:21:18.891 26268-26268/me.dbw9580.apps.BridgeTooth D/BluetoothAdapter: isLeEnabled(): ON

I have created a pull request #10 that tries to solve this by using a local flag. I have tried mutex locks, but they only work when the shared object is accessed from two different threads. In our situation, it seems that the callback is executed on the same thread as the other codes, so they do not work. I am not aware of any better solution, though.

I have tested the fix in my own application on Android 8.0 on a Sony XZ1 Compact device, and it seems to be working fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant