Skip to content

Commit

Permalink
reconnect logic cap timeout and try forever
Browse files Browse the repository at this point in the history
  • Loading branch information
crc-32 committed Jun 15, 2024
1 parent 49233bc commit 7161c88
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package io.rebble.cobble.bluetooth
import android.bluetooth.BluetoothAdapter
import android.companion.CompanionDeviceManager
import android.content.Context
import android.os.Build
import androidx.annotation.RequiresPermission
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.MutableStateFlow
Expand All @@ -13,6 +14,7 @@ import javax.inject.Inject
import javax.inject.Singleton
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
import kotlin.math.min

@OptIn(ExperimentalCoroutinesApi::class)
@Singleton
Expand Down Expand Up @@ -73,6 +75,7 @@ class ConnectionLooper @Inject constructor(
launchRestartOnBluetoothOff(macAddress)

var retryTime = HALF_OF_INITAL_RETRY_TIME
var retries = 0
while (isActive) {
if (BluetoothAdapter.getDefaultAdapter()?.isEnabled != true) {
Timber.d("Bluetooth is off. Waiting until it is on Cancel connection attempt.")
Expand All @@ -95,6 +98,7 @@ class ConnectionLooper @Inject constructor(
}
if (it is SingleConnectionStatus.Connected) {
retryTime = HALF_OF_INITAL_RETRY_TIME
retries = 0
}
}
} catch (_: CancellationException) {
Expand All @@ -106,13 +110,9 @@ class ConnectionLooper @Inject constructor(

val lastWatch = connectionState.value.watchOrNull

retryTime *= 2
if (retryTime > MAX_RETRY_TIME) {
Timber.d("Watch failed to connect after numerous attempts. Abort connection.")

break
}
Timber.d("Watch connection failed, waiting and reconnecting after $retryTime ms")
retryTime = min(retryTime + HALF_OF_INITAL_RETRY_TIME, MAX_RETRY_TIME)
retries++
Timber.d("Watch connection failed, waiting and reconnecting after $retryTime ms (retry: $retries)")
_connectionState.value = ConnectionState.WaitingForReconnect(lastWatch)
delayJob = launch {
delay(retryTime)
Expand All @@ -122,6 +122,7 @@ class ConnectionLooper @Inject constructor(
} catch (_: CancellationException) {
Timber.i("Reconnect delay interrupted")
retryTime = HALF_OF_INITAL_RETRY_TIME
retries = 0
}
}
} finally {
Expand Down Expand Up @@ -151,7 +152,9 @@ class ConnectionLooper @Inject constructor(
fun closeConnection() {
lastConnectedWatch?.let {
val companionDeviceManager = context.getSystemService(CompanionDeviceManager::class.java)
companionDeviceManager.stopObservingDevicePresence(it)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
companionDeviceManager.stopObservingDevicePresence(it)
}
}
currentConnection?.cancel()
}
Expand Down Expand Up @@ -187,4 +190,4 @@ private fun SingleConnectionStatus.toConnectionStatus(): ConnectionState {
}

private const val HALF_OF_INITAL_RETRY_TIME = 2_000L // initial retry = 4 seconds
private const val MAX_RETRY_TIME = 10 * 3600 * 1000L // 10 hours
private const val MAX_RETRY_TIME = 10_000L // Max retry = 10 seconds
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,15 @@ class DeviceTransport @Inject constructor(
bleScanner.stopScan()
classicScanner.stopScan()

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val companionDeviceManager = context.getSystemService(CompanionDeviceManager::class.java)
Timber.d("Companion device associated: ${macAddress in companionDeviceManager.associations}, associations: ${companionDeviceManager.associations}")
val companionDeviceManager = context.getSystemService(CompanionDeviceManager::class.java)
Timber.d("Companion device associated: ${macAddress in companionDeviceManager.associations}, associations: ${companionDeviceManager.associations}")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
lastMacAddress?.let {
companionDeviceManager.stopObservingDevicePresence(it)
}
lastMacAddress = macAddress
companionDeviceManager.startObservingDevicePresence(macAddress)
}
lastMacAddress = macAddress

val bluetoothDevice = if (BuildConfig.DEBUG && !macAddress.contains(":")) {
PebbleDevice(null, true, macAddress)
Expand Down

0 comments on commit 7161c88

Please sign in to comment.