First off — thanks for AirSync.
While reading through the source (main @ 3f3b494) I (AI) went looking for how the app behaves when the Mac is off or out of range for a long stretch, and I wanted to check a few observations with you before assuming I've misread something.
What I think I'm seeing
1. The retry interval settles at 10 s and stays there
In WebSocketUtil.tryStartAutoReconnect():
var backoffMs = 2000L
while (autoReconnectActive.get() && !isConnected()) {
...connect(...)
delay(backoffMs)
backoffMs = (backoffMs * 1.5).toLong().coerceAtMost(10_000L)
}
So the progression is 2 s → 3 → 4.5 → 6.75 → 10 → 10 → 10 … and the loop exits only on success, on manual disconnect, or when auto-reconnect is switched off. If the Mac stays off all day, that's roughly 8,600 attempts. I couldn't find a second-tier escalation anywhere (I grepped for WorkManager, AlarmManager and minute-scale constants) — is a longer ceiling something you'd already considered? I noticed autoReconnectAttempts and autoReconnectStartTime are assigned but never read, which made me wonder whether something along those lines was already planned.
2. The Wi-Fi lock is held across the whole loop
acquireWifiLock() is called once before the retry loop starts and WIFI_MODE_FULL_LOW_LATENCY is held until cancelAutoReconnect() runs. Would it make sense to acquire it around individual attempts instead, so the idle gaps aren't covered?
3. isLocalNetwork() checks the target address rather than reachability
if (ipAddress.startsWith("192.168.") || ipAddress.startsWith("10.") || ...
A stored Mac address always passes this check, so as far as I can tell the loop still calls connect() when the phone has no Wi-Fi association at all. Since the OkHttp client isn't bound to a specific Network, I think that means the attempt goes out over the default route — i.e. over cellular, where it can't succeed. I haven't verified this on a device, so I may well be wrong about what actually happens on the wire. Would a "do we currently have a network whose subnet matches a known address" pre-check be worth adding before the attempt?
The bit I found most interesting
AirSyncService.registerNetworkCallback() already consults BLE state:
if (isScanning && !BleGattServer.isAnyAuthenticated()) {
DiscoveryOrchestrator.burstBroadcast(applicationContext)
WebSocketUtil.requestAutoReconnect(applicationContext)
} else if (isScanning) {
DiscoveryOrchestrator.burstBroadcast(applicationContext)
}
That uses BLE as a suppressor once a BLE link exists. What occurred to me is the inverse: BLE absence is also a reasonably strong hint that the Mac isn't nearby, and it's far cheaper to keep an advertisement running than to retry a TCP connection every 10 s.
I don't think "no BLE ⇒ stop entirely" would be right — BLE range is much shorter than Wi-Fi, a Mac two rooms away is reachable over the LAN but not over BLE, and Bluetooth may simply be off. But something graduated might fit:
- BLE peer visible → connect promptly, as today
- no BLE peer → keep retrying, but with a much longer ceiling (30 s → 2 min → 5 min?), and let discovery/wake-up handle the fast path
Since the Mac already sends a unicast wake-up via QuickConnectManager and bursts presence packets on launch/wake/network change, a slow Wi-Fi retry seems like it would still be enough of a safety net.
Why I'm asking
I'm only at my laptop for part of the day, so I got curious about what the Android side costs while there's simply no connection to be had. I'd also rather not have to flip auto-reconnect on and off by hand depending on where I happen to be.
To be clear, I haven't measured any of this — I was reading through the code out of interest rather than chasing an actual battery problem. If the cost of looking for a peer is small enough to go unnoticed in practice, please feel free to ignore all of this; I was mostly just curious.
Related: #131 (global on/off toggle) covers some of the same ground from the UX side, though this is more about what happens when the app is left in its default state.
Thanks again for the project.
First off — thanks for AirSync.
While reading through the source (main @
3f3b494) I (AI) went looking for how the app behaves when the Mac is off or out of range for a long stretch, and I wanted to check a few observations with you before assuming I've misread something.What I think I'm seeing
1. The retry interval settles at 10 s and stays there
In
WebSocketUtil.tryStartAutoReconnect():So the progression is 2 s → 3 → 4.5 → 6.75 → 10 → 10 → 10 … and the loop exits only on success, on manual disconnect, or when auto-reconnect is switched off. If the Mac stays off all day, that's roughly 8,600 attempts. I couldn't find a second-tier escalation anywhere (I grepped for
WorkManager,AlarmManagerand minute-scale constants) — is a longer ceiling something you'd already considered? I noticedautoReconnectAttemptsandautoReconnectStartTimeare assigned but never read, which made me wonder whether something along those lines was already planned.2. The Wi-Fi lock is held across the whole loop
acquireWifiLock()is called once before the retry loop starts andWIFI_MODE_FULL_LOW_LATENCYis held untilcancelAutoReconnect()runs. Would it make sense to acquire it around individual attempts instead, so the idle gaps aren't covered?3.
isLocalNetwork()checks the target address rather than reachabilityA stored Mac address always passes this check, so as far as I can tell the loop still calls
connect()when the phone has no Wi-Fi association at all. Since the OkHttp client isn't bound to a specificNetwork, I think that means the attempt goes out over the default route — i.e. over cellular, where it can't succeed. I haven't verified this on a device, so I may well be wrong about what actually happens on the wire. Would a "do we currently have a network whose subnet matches a known address" pre-check be worth adding before the attempt?The bit I found most interesting
AirSyncService.registerNetworkCallback()already consults BLE state:That uses BLE as a suppressor once a BLE link exists. What occurred to me is the inverse: BLE absence is also a reasonably strong hint that the Mac isn't nearby, and it's far cheaper to keep an advertisement running than to retry a TCP connection every 10 s.
I don't think "no BLE ⇒ stop entirely" would be right — BLE range is much shorter than Wi-Fi, a Mac two rooms away is reachable over the LAN but not over BLE, and Bluetooth may simply be off. But something graduated might fit:
Since the Mac already sends a unicast wake-up via
QuickConnectManagerand bursts presence packets on launch/wake/network change, a slow Wi-Fi retry seems like it would still be enough of a safety net.Why I'm asking
I'm only at my laptop for part of the day, so I got curious about what the Android side costs while there's simply no connection to be had. I'd also rather not have to flip auto-reconnect on and off by hand depending on where I happen to be.
To be clear, I haven't measured any of this — I was reading through the code out of interest rather than chasing an actual battery problem. If the cost of looking for a peer is small enough to go unnoticed in practice, please feel free to ignore all of this; I was mostly just curious.
Related: #131 (global on/off toggle) covers some of the same ground from the UX side, though this is more about what happens when the app is left in its default state.
Thanks again for the project.