Closed roland-ryan-rm closed 6 days ago
Hello,
The change to which you pointed added an empty ScanFilter
, which seemed to work back then in background.
I see in Android code: https://cs.android.com/android/platform/superproject/main/+/main:packages/modules/Bluetooth/android/app/src/com/android/bluetooth/le_scan/ScanManager.java;drc=d4587ecc9318a57c043a2c10dad692709a884e91;bpv=1;bpt=1;l=460 that indeed, screen on is required if all filters are empty.
I think we could fix the issue and simplify it by adding non-empty filters form some Android version. Could you try the DFU background scan on older Android device and try to find at what point has it stopped working?
Here's the commit that "fixed" that: https://cs.android.com/android/_/android/platform/packages/modules/Bluetooth/+/7f707ac3123f62e78cc090b934d3146326fc52bc:android/app/src/com/android/bluetooth/gatt/ScanManager.java;dlc=4f3c7a98febe594469dd1bd82e0086c24bbc3b51 which would indicate API 33 or 34 (June 2023).
I think we could fix the issue and simplify it by adding non-empty filters form some Android version. Could you try the DFU background scan on older Android device and try to find at what point has it stopped working?
Here's the commit that "fixed" that: https://cs.android.com/android/_/android/platform/packages/modules/Bluetooth/+/7f707ac3123f62e78cc090b934d3146326fc52bc:android/app/src/com/android/bluetooth/gatt/ScanManager.java;dlc=4f3c7a98febe594469dd1bd82e0086c24bbc3b51 which would indicate API 33 or 34 (June 2023).
I just tried it with a device running API 31 and still had the issue, but a different device running API 29 did not have the issue. So I'd guess the breaking change was made in API 30 or 31.
Awesome, thanks for the quick turnaround on this! @philips77 any idea when the next release will be?
I have one more thing to fix in the app. I'll release tomorrow.
Can confirm the fix works after properly overriding getDeviceSelector()
in my subclass of DfuBaseService
. Code is below, for anyone else that may run into this issue. Thanks for the quick turnaround on this!
private var deviceAddress: String? = null
override fun onHandleIntent(intent: Intent?) {
super.onHandleIntent(intent)
deviceAddress = intent?.getStringExtra(EXTRA_DEVICE_ADDRESS)
}
override fun getDeviceSelector(): DfuDeviceSelector {
return CustomDeviceSelector()
}
inner class CustomDeviceSelector : DfuDeviceSelector {
override fun matches(
device: BluetoothDevice,
rssi: Int,
scanRecord: ByteArray,
originalAddress: String,
incrementedAddress: String
): Boolean {
return originalAddress == device.address || incrementedAddress == device.address
}
override fun getScanFilters(dfuServiceUuid: ParcelUuid): MutableList<ScanFilter> {
return mutableListOf<ScanFilter>().apply {
add(ScanFilter.Builder().setServiceUuid(dfuServiceUuid).build())
deviceAddress?.let {
add(ScanFilter.Builder().setDeviceAddress(it).build())
add(ScanFilter.Builder().setDeviceAddress(BootloaderScannerFactory.getIncrementedAddress(it)).build())
}
}
}
}
Where do you suspect the issue?
Issue in DFU library, e.g. upload stops in the middle
Version
2.5.0 (Latest)
Describe the issue
When the Android screen is off, the DFU fails right after starting. This appears to be because the scanner cannot find the Android device. Our app has already been granted the
ACCESS_BACKGROUND_LOCATION
permission, so that's not relevant in this case.After some investigation, it seems to me like the issue was introduced here. The removal of the scan filters, obstensibly to resolve issues with the DFU working at all on some devices (as seen here), stops the bluetooth scanner from being able to find the device to perform the DFU on when the screen is off.
After downloading the source code and changing
BootloaderScannerLollipop
to use those filters again, I can confirm that using the filters resolves this issue.Could an option of some sort be added to allow developers to choose to support DFUs with the screen off? It would seem silly to have to fork this SDK just to support something that it already supported two years ago.
Relevant log output