Fix BT app not updating when toggling on BT

This commit is contained in:
Ken Van Hoeylandt 2026-07-28 00:25:56 +02:00
parent e6e1dcd0ca
commit 4e97ae46e7
3 changed files with 22 additions and 3 deletions

View File

@ -13,7 +13,6 @@
## Higher Priority
- Bluetooth app: when toggling BT on, it doesn't update the UI with discovered devices. It only works after re-opening the app.
- display.h API: get_backlight does not change ref counting, but it should
- bluetooth: various getters for child devices do not change ref counting, but they should
- Improve kernel_init.cpp (and other modules): create driver_ensure_added() and driver_ensure_destructed()

View File

@ -35,6 +35,12 @@ public:
State& getState() { return state; }
void requestViewUpdate();
// Re-attempts registering the device event callback. Needed because the BLE driver
// only allocates its callback list while the device is started/on: a registration
// attempted while the radio is off silently no-ops, so this must be called again
// right after a successful bluetooth::start().
void registerDeviceCallback(Device* dev);
};
} // namespace tt::app::btmanage

View File

@ -23,7 +23,13 @@ static void onBtToggled(bool requestOn) {
bool radio_on = bluetooth::isRadioOnOrPending(dev);
if (requestOn && !radio_on) {
LOG_I(TAG, "Turning on");
bluetooth::start(dev);
if (bluetooth::start(dev)) {
// The driver only allocates its callback list once the device is started,
// so the registration attempted in onShow() (while radio was off) was a
// no-op. Register again now that the device is actually up.
auto bt = std::static_pointer_cast<BtManage>(getCurrentApp());
bt->registerDeviceCallback(dev);
}
} else if (!requestOn && radio_on) {
LOG_I(TAG, "Turning off");
bluetooth::stop(dev);
@ -153,12 +159,20 @@ static void onKernelBtEvent(Device* /*device*/, void* context, BtEvent event) {
});
}
void BtManage::registerDeviceCallback(Device* dev) {
lock();
if (btDevice == dev) {
bluetooth_add_event_callback(dev, this, onKernelBtEvent);
}
unlock();
}
void BtManage::onShow(AppContext& app, lv_obj_t* parent) {
// Initialise state and view before subscribing to avoid incoming events
// racing with state initialisation.
state.setRadioState(bluetooth::getRadioState());
Device* dev = nullptr;
device_get_first_active_by_type(&BLUETOOTH_TYPE, &dev);
device_get_first_by_type(&BLUETOOTH_TYPE, &dev);
state.setScanning(dev ? bluetooth_is_scanning(dev) : false);
state.updateScanResults();