Fix: Show device settings immediately after opening the app#485
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
Device Settings for a paired AirPods profile could briefly appear blank right after opening CAPod if the app was launched before the AirPods had a chance to report their first battery update. The screen now populates immediately, with controls showing up as soon as the AirPods reconnect. Similarly, the Overview card and home-screen widget for that profile now show up during the same window instead of being temporarily absent.
Also fixes a subtle correctness issue: after a model correction on a paired device, a stale cached value could keep shadowing the updated profile model until the next battery message arrived. Profiles now win over cache for model and bonded address lookups, so corrections take effect right away.
Technical Context
Follow-up to #484, which fixed the mid-session case (BLE goes stale while AAP stays alive, profile has a cache). This PR addresses the deferred cold-start case:
AapAutoConnect.initialConnect()is keyed oncombine(profilesRepo.profiles, bluetoothManager.connectedDevices)— entirely independent of BLE detection.aapManager.allStates[address]populates as soon asconnect()is called (state =CONNECTING), before any handshake or battery message.toCachedState()returnsnulluntil at least one battery value arrives, so the cache stays empty until the first AAP battery notification (~5-30 s post-READY). Opening DeviceSettings during that window previously hitdevices.firstOrNull { it.address == address } == nulland rendered a blank screen.PodDevicegained two optional internal fieldsprofileAddress/profileModeland itsaddress/modelgetters now fall through to them. Call sites are all named-arg so this is additive.ble → profile → cache → fallback(wasble → cache → fallback). The profile is the user-authoritative source after a model correction or explicit edit; cache is a stale snapshot. No regression expected for normal flow because cache is re-written on every battery message.DeviceMonitor.devicescollapsed the previous two-branch merge (live + cached-only) into a single non-live pass that covers cache-only, AAP-only, and cache+AAP in one mapNotNull.PodDevice's getters already fall throughcachedandaapindependently, so the branches had no reason to be separate.getDeviceForProfile(suspend fallback used by the widget) now looks up AAP state in addition to cache, and plumbsprofileAddress/profileModelthrough.address+identityKeyset but BLE detection can't IRK-match (e.g. wrong keys) — we'd otherwise show two cards for the same physical pods. Model match only, since BLE addresses are RPAs and can't be compared directly; at most one anonymous pod per matching model is hidden so a legitimate second physical device of the same model stays visible.DeviceMonitorTestcases — AAP-only synthesis (CONNECTING + READY), negative case,getDeviceForProfile× 2, stale-cache vs updated profile precedence × 2, de-dupe positive + negative.computeAapBoost. Minor cosmetic, deferred — fixing it would mean hiding the badge whenble == nullor adding a separate AAP-connecting indicator.Review guidance
ble → profile → cache) is intentional and widens beyond the cold-start case. Worth double-checking the two stale-cache tests (stale cache vs updated profile model/address) match your expectation.dedupedLiveDevicesblock can be removed.getDeviceForProfileis hit byBatteryGlanceWidget, so the widget benefits from the same cold-start improvement automatically.