Skip to content

Commit d05d1c9

Browse files
sk7n4k3dclaude
authored andcommitted
Address Copilot review feedback on push provider abstraction
- Remove suspend from WebsocketManager.restart() (no suspending calls) - Remove unused context parameter from WebSocketPushProvider - Clear server-side push config when switching to WebSocket - Rethrow CancellationException in PushProviderManager and FcmPushProvider - Derive initial push provider from available providers instead of hardcoded default - Stabilize getAllProviders() ordering with sortedBy name - Fix PushProvider KDoc to reflect user-selection model - Wire handlePushProviderChange to actually call selectAndRegister - Remove dead getString/putString cases for notification_push_provider - Move push provider label resolution to Fragment using string resources Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 37100c9 commit d05d1c9

File tree

9 files changed

+32
-30
lines changed

9 files changed

+32
-30
lines changed

app/src/full/kotlin/io/homeassistant/companion/android/push/FcmPushProvider.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import io.homeassistant.companion.android.common.push.PushRegistrationResult
55
import io.homeassistant.companion.android.common.util.MessagingTokenProvider
66
import javax.inject.Inject
77
import javax.inject.Singleton
8+
import kotlin.coroutines.cancellation.CancellationException
89
import timber.log.Timber
910

1011
/**
@@ -24,6 +25,7 @@ class FcmPushProvider @Inject constructor(
2425
val token = messagingTokenProvider()
2526
!token.isBlank()
2627
} catch (e: Exception) {
28+
if (e is CancellationException) throw e
2729
Timber.e(e, "FCM is not available")
2830
false
2931
}
@@ -34,6 +36,7 @@ class FcmPushProvider @Inject constructor(
3436
val token = messagingTokenProvider()
3537
!token.isBlank()
3638
} catch (e: Exception) {
39+
if (e is CancellationException) throw e
3740
false
3841
}
3942
}
@@ -52,6 +55,7 @@ class FcmPushProvider @Inject constructor(
5255
)
5356
}
5457
} catch (e: Exception) {
58+
if (e is CancellationException) throw e
5559
Timber.e(e, "Failed to register FCM")
5660
null
5761
}

app/src/main/kotlin/io/homeassistant/companion/android/push/WebSocketPushProvider.kt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package io.homeassistant.companion.android.push
22

3-
import android.content.Context
4-
import dagger.hilt.android.qualifiers.ApplicationContext
53
import io.homeassistant.companion.android.common.data.servers.ServerManager
64
import io.homeassistant.companion.android.common.push.PushProvider
75
import io.homeassistant.companion.android.common.push.PushRegistrationResult
@@ -19,7 +17,6 @@ import timber.log.Timber
1917
*/
2018
@Singleton
2119
class WebSocketPushProvider @Inject constructor(
22-
@ApplicationContext private val context: Context,
2320
private val serverManager: ServerManager,
2421
private val settingsDao: SettingsDao,
2522
) : PushProvider {

app/src/main/kotlin/io/homeassistant/companion/android/settings/SettingsFragment.kt

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -555,22 +555,21 @@ class SettingsFragment(
555555
}
556556
if (value == "WebSocket") {
557557
Toast.makeText(requireContext(), commonR.string.push_provider_websocket_enabled, Toast.LENGTH_SHORT).show()
558-
lifecycleScope.launch {
559-
WebsocketManager.restart(requireContext())
560-
}
558+
WebsocketManager.restart(requireContext())
561559
}
562560
true
563561
}
564562

565563
lifecycleScope.launch(Dispatchers.IO) {
566-
val entries = mutableListOf<String>()
567-
val values = mutableListOf<String>()
568-
569-
val providers = presenter.getAvailablePushProviders()
570-
for (provider in providers) {
571-
entries.add(provider.second)
572-
values.add(provider.first)
573-
}
564+
val providerNames = presenter.getAvailablePushProviders()
565+
val values = providerNames.toMutableList()
566+
val entries = providerNames.map { name ->
567+
when (name) {
568+
"FCM" -> getString(commonR.string.push_provider_fcm)
569+
"WebSocket" -> getString(commonR.string.push_provider_websocket)
570+
else -> name
571+
}
572+
}.toMutableList()
574573

575574
val activeValue = presenter.getActivePushProviderValue()
576575

app/src/main/kotlin/io/homeassistant/companion/android/settings/SettingsPresenter.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ interface SettingsPresenter {
2424
suspend fun showChangeLog(context: Context)
2525
suspend fun isChangeLogPopupEnabled(): Boolean
2626
suspend fun setChangeLogPopupEnabled(enabled: Boolean)
27-
fun getAvailablePushProviders(): List<Pair<String, String>>
27+
fun getAvailablePushProviders(): List<String>
2828
fun getActivePushProviderValue(): String
2929
fun handlePushProviderChange(value: String?)
3030
}

app/src/main/kotlin/io/homeassistant/companion/android/settings/SettingsPresenterImpl.kt

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,6 @@ class SettingsPresenterImpl @Inject constructor(
116116
"languages" -> langsManager.getCurrentLang()
117117
"page_zoom" -> prefsRepository.getPageZoomLevel().toString()
118118
"screen_orientation" -> prefsRepository.getScreenOrientation()
119-
"notification_push_provider" -> selectedPushProvider
120119
else -> throw IllegalArgumentException("No string found by this key: $key")
121120
}
122121
}
@@ -128,7 +127,6 @@ class SettingsPresenterImpl @Inject constructor(
128127
"languages" -> langsManager.saveLang(value)
129128
"page_zoom" -> prefsRepository.setPageZoomLevel(value?.toIntOrNull())
130129
"screen_orientation" -> prefsRepository.saveScreenOrientation(value)
131-
"notification_push_provider" -> handlePushProviderChange(value)
132130
else -> throw IllegalArgumentException("No string found by this key: $key")
133131
}
134132
}
@@ -223,25 +221,21 @@ class SettingsPresenterImpl @Inject constructor(
223221
}
224222
}
225223

226-
override fun getAvailablePushProviders(): List<Pair<String, String>> {
227-
return pushProviderManager.getAllProviders().map { provider ->
228-
val label = when (provider.name) {
229-
"FCM" -> "Firebase Cloud Messaging"
230-
"WebSocket" -> "WebSocket"
231-
else -> provider.name
232-
}
233-
provider.name to label
234-
}
224+
override fun getAvailablePushProviders(): List<String> {
225+
return pushProviderManager.getAllProviders().map { it.name }
235226
}
236227

237228
override fun getActivePushProviderValue(): String {
238229
selectedPushProvider?.let { return it }
239-
return "WebSocket"
230+
return pushProviderManager.getAllProviders().firstOrNull()?.name ?: "WebSocket"
240231
}
241232

242233
override fun handlePushProviderChange(value: String?) {
243234
if (value == null) return
244235
selectedPushProvider = value
236+
mainScope.launch {
237+
pushProviderManager.selectAndRegister(value)
238+
}
245239
}
246240

247241
private fun enableLauncherMode(enable: Boolean) {

app/src/main/kotlin/io/homeassistant/companion/android/websocket/WebsocketManager.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ class WebsocketManager(appContext: Context, workerParams: WorkerParameters) :
6262
WebsocketSetting.ALWAYS
6363
}
6464

65-
suspend fun restart(context: Context) {
65+
fun restart(context: Context) {
6666
val websocketNotifications =
6767
PeriodicWorkRequestBuilder<WebsocketManager>(15, TimeUnit.MINUTES)
6868
.build()

common/src/main/kotlin/io/homeassistant/companion/android/common/data/integration/impl/IntegrationRepositoryImpl.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,11 @@ class IntegrationRepositoryImpl @AssistedInject constructor(
690690
appData["push_url"] = pushUrl
691691
appData["push_token"] = ""
692692
appData["push_encrypt"] = false
693+
} else {
694+
// No token and no URL: explicitly clear server-side push config (e.g. when switching to WebSocket)
695+
appData["push_url"] = ""
696+
appData["push_token"] = ""
697+
appData["push_encrypt"] = false
693698
}
694699

695700
return RegisterDeviceRequest(

common/src/main/kotlin/io/homeassistant/companion/android/common/push/PushProvider.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ package io.homeassistant.companion.android.common.push
99
* - Indicating whether it requires a persistent connection (e.g. WebSocket)
1010
*
1111
* Implementations should be registered via Dagger multibinding so that
12-
* [PushProviderManager] can select the best available provider at runtime.
12+
* [PushProviderManager] can discover all available providers and expose them
13+
* for user selection.
1314
*/
1415
interface PushProvider {
1516

common/src/main/kotlin/io/homeassistant/companion/android/common/push/PushProviderManager.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import io.homeassistant.companion.android.common.data.servers.ServerManager
55
import io.homeassistant.companion.android.common.util.MessagingToken
66
import javax.inject.Inject
77
import javax.inject.Singleton
8+
import kotlin.coroutines.cancellation.CancellationException
89
import timber.log.Timber
910

1011
/**
@@ -27,7 +28,7 @@ class PushProviderManager @Inject constructor(
2728
/**
2829
* Get all registered providers.
2930
*/
30-
fun getAllProviders(): List<PushProvider> = providers.toList()
31+
fun getAllProviders(): List<PushProvider> = providers.sortedBy { it.name }
3132

3233
/**
3334
* Get a provider by name.
@@ -95,6 +96,7 @@ class PushProviderManager @Inject constructor(
9596
allowReregistration = false,
9697
)
9798
} catch (e: Exception) {
99+
if (e is CancellationException) throw e
98100
Timber.e(e, "Failed to update push registration for server ${server.id}")
99101
}
100102
}

0 commit comments

Comments
 (0)