Skip to content

Add generic PushProvider abstraction for notification delivery#6619

Draft
sk7n4k3d wants to merge 5 commits intohome-assistant:mainfrom
sk7n4k3d:push-provider-abstraction
Draft

Add generic PushProvider abstraction for notification delivery#6619
sk7n4k3d wants to merge 5 commits intohome-assistant:mainfrom
sk7n4k3d:push-provider-abstraction

Conversation

@sk7n4k3d
Copy link
Copy Markdown

@sk7n4k3d sk7n4k3d commented Mar 23, 2026

Summary

  • Introduces a PushProvider interface that abstracts push notification delivery, allowing users to choose their preferred provider
  • Adds PushProviderManager for provider selection and server registration
  • Implements FcmPushProvider (full flavor) and WebSocketPushProvider as built-in providers
  • Adds a new "Push provider" setting under Notifications, always visible, letting users switch providers without app restart
  • Extends DeviceRegistration with pushUrl and pushEncrypt fields for future provider support
  • Adds WebsocketManager.restart() for instant WebSocket push channel resubscription on provider switch

This is the first of two PRs splitting the UnifiedPush work as requested in #6599. This PR contains only the generic abstraction layer — no UnifiedPush-specific code. The second PR (#TBD) will add the UnifiedPush implementation on top.

Testing

  • Tested on Pixel 9 Pro Fold (Android 16, GrapheneOS)
  • Both full and minimal flavors compile and pass tests
  • 28 unit tests for PushProvider interface and PushProviderManager

Type of change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update

Copilot AI review requested due to automatic review settings March 23, 2026 21:39
Copy link
Copy Markdown

@home-assistant home-assistant bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @aaronstealth

It seems you haven't yet signed a CLA. Please do so here.

Once you do that we will be able to review and accept this pull request.

Thanks!

@home-assistant home-assistant bot marked this pull request as draft March 23, 2026 21:39
@home-assistant
Copy link
Copy Markdown

Please take a look at the requested changes, and use the Ready for review button when you are done, thanks 👍

Learn more about our pull request process.

@sk7n4k3d sk7n4k3d marked this pull request as ready for review March 23, 2026 21:41
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new push-notification provider abstraction layer to the Android companion app, aiming to enable multiple push delivery mechanisms (FCM, WebSocket, and future providers) behind a common interface and expose a user-selectable provider setting.

Changes:

  • Introduces PushProvider + PushProviderManager and adds unit tests for the abstraction layer
  • Extends device registration payload/storage to include pushUrl and pushEncrypt
  • Adds a new “Push provider” ListPreference plus WebSocket/FCM provider implementations and Dagger multibindings

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
common/src/main/kotlin/io/homeassistant/companion/android/common/push/PushProvider.kt New push provider interface + registration result model
common/src/main/kotlin/io/homeassistant/companion/android/common/push/PushProviderManager.kt Provider selection + server registration update helper
common/src/main/kotlin/io/homeassistant/companion/android/common/data/integration/DeviceRegistration.kt Adds pushUrl and pushEncrypt fields to registration model
common/src/main/kotlin/io/homeassistant/companion/android/common/data/integration/impl/IntegrationRepositoryImpl.kt Persists pushUrl and sends push_url/push_encrypt during registration updates
common/src/main/res/values/strings.xml Adds strings for the new push provider setting
common/src/test/kotlin/io/homeassistant/companion/android/common/push/PushProviderTest.kt Unit tests for default interface behaviors and PushRegistrationResult
common/src/test/kotlin/io/homeassistant/companion/android/common/push/PushProviderManagerTest.kt Unit tests for provider manager selection and server update behavior
app/src/main/res/xml/preferences.xml Adds “Push provider” ListPreference under Notifications
app/src/main/kotlin/io/homeassistant/companion/android/settings/SettingsPresenter.kt Adds presenter APIs for push provider list/value/change
app/src/main/kotlin/io/homeassistant/companion/android/settings/SettingsPresenterImpl.kt Implements push provider list/value/change (currently in-memory)
app/src/main/kotlin/io/homeassistant/companion/android/settings/SettingsFragment.kt Populates ListPreference entries dynamically and restarts WebSocket worker when selected
app/src/main/kotlin/io/homeassistant/companion/android/websocket/WebsocketManager.kt Adds restart() helper to re-enqueue periodic WebSocket worker
app/src/main/kotlin/io/homeassistant/companion/android/push/WebSocketPushProvider.kt WebSocket-backed PushProvider implementation
app/src/full/kotlin/io/homeassistant/companion/android/push/FcmPushProvider.kt Full-flavor FCM-backed PushProvider implementation
app/src/full/kotlin/io/homeassistant/companion/android/push/PushProviderModule.kt Hilt multibinding module for full flavor providers
app/src/minimal/kotlin/io/homeassistant/companion/android/push/PushProviderModule.kt Hilt multibinding module for minimal flavor providers

Copy link
Copy Markdown

@home-assistant home-assistant bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @aaronstealth

It seems you haven't yet signed a CLA. Please do so here.

Once you do that we will be able to review and accept this pull request.

Thanks!

@home-assistant home-assistant bot marked this pull request as draft March 23, 2026 22:42
@sk7n4k3d sk7n4k3d force-pushed the push-provider-abstraction branch from d84a596 to d05d1c9 Compare March 24, 2026 12:34
@sk7n4k3d sk7n4k3d marked this pull request as ready for review March 24, 2026 13:13
@TimoPtr TimoPtr marked this pull request as draft March 25, 2026 15:36
@TimoPtr
Copy link
Copy Markdown
Member

TimoPtr commented Mar 25, 2026

Check the CI and also the comments from Copilot and then put the PR ready for review again once ready.

@sk7n4k3d
Copy link
Copy Markdown
Author

All Copilot review comments addressed and ktlint fixed:

  • 10/11 comments were already resolved in previous commits (CancellationException handling, persistence, provider switching, string resources, etc.)
  • Fixed remaining KDoc inconsistency in PushProvider.kt
  • ktlint formatting fixed (import ordering, constructor params, argument wrapping)

CI should pass now. Ready for review.

@sk7n4k3d sk7n4k3d marked this pull request as ready for review March 25, 2026 15:58
@TimoPtr TimoPtr marked this pull request as draft March 26, 2026 09:54
@TimoPtr
Copy link
Copy Markdown
Member

TimoPtr commented Mar 26, 2026

CI is failing on building the wear module

@sk7n4k3d
Copy link
Copy Markdown
Author

@TimoPtr Fixed the wear build failure. The issue was positional arguments in DeviceRegistration() calls — when pushUrl and pushEncrypt were added, the false meant for pushWebsocket ended up in pushUrl: String?.

Switched to named parameters in both wear files so it's resilient to parameter order changes.

CI should be green now.

sk7n4k3d and others added 3 commits April 9, 2026 21:19
Introduce a PushProvider interface that abstracts push notification
delivery, allowing the user to choose between available providers
(FCM, WebSocket) via a new "Push provider" setting under Notifications.

This lays the groundwork for additional providers (e.g. UnifiedPush)
without coupling the abstraction to any specific implementation.

- Add PushProvider interface with name, isAvailable, isActive, register,
  unregister, and requiresPersistentConnection
- Add PushProviderManager for provider selection and server registration
- Add FcmPushProvider (full flavor) and WebSocketPushProvider
- Add Dagger multibinding modules for both flavors
- Add "Push provider" ListPreference in Notifications settings
- Add WebsocketManager.restart() for instant provider switching
- Extend DeviceRegistration with pushUrl and pushEncrypt fields
- Add 28 unit tests for PushProvider and PushProviderManager

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- 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>
- Persist selectedPushProvider via PrefsRepository instead of in-memory
  variable to survive process death
- Trigger server-side registration update when push provider changes
  by calling updateServerRegistration after selectAndRegister
- Add explanatory comment for preferenceDataStore = null in
  SettingsFragment push provider preference
- Replace hardcoded "WebSocket" fallback with WebSocketPushProvider.NAME
  constant reference

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
sk7n4k3d added 2 commits April 9, 2026 21:19
…ment

- Fix import ordering in SettingsFragment.kt and SettingsPresenterImpl.kt
- Fix argument wrapping for Toast.makeText call in SettingsFragment.kt
- Fix constructor parameter formatting in FcmPushProvider.kt
- Clarify PushProvider KDoc: explicitly note user-configurable selection
  with no automatic "best provider" logic
The positional args broke when pushUrl/pushEncrypt were added to
DeviceRegistration. Boolean was being passed where String? was
expected. Named parameters make this resilient to parameter order.
@sk7n4k3d sk7n4k3d force-pushed the push-provider-abstraction branch from bd375c8 to 54b225f Compare April 9, 2026 19:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants