Skip to content

Introduce FrontendTarget and use it instead of WebViewActivity - #7087

Merged
jpelgrom merged 6 commits into
mainfrom
feature/more-info_deep-link
Jul 8, 2026
Merged

Introduce FrontendTarget and use it instead of WebViewActivity#7087
jpelgrom merged 6 commits into
mainfrom
feature/more-info_deep-link

Conversation

@TimoPtr

@TimoPtr TimoPtr commented Jun 24, 2026

Copy link
Copy Markdown
Member

Summary

The support for the deep link more-info was not complete it was missing the fallback case for old server, in order to make it right I've decided to introduce the FrontendTarget sealed interface. I've also replace most of the call to WebViewActivity.newInstance it only remains one usage in ManageShortcutsViewModel we need to migrate to LinkActivity #7086.

I've also made sure that the given parameter cannot extend more than just the entityID in the URL or JS evaluation.

Checklist

  • New or updated tests have been added to cover the changes following the testing guidelines.
  • The code follows the project's code style and best_practices.
  • The changes have been thoroughly tested, and edge cases have been considered.
  • Changes are backward compatible whenever feasible. Any breaking changes are documented in the changelog for users and/or in the code for developers depending on the relevance.

Copilot AI review requested due to automatic review settings June 24, 2026 14:57
@TimoPtr TimoPtr added the WebViewActivity replacement Ongoing work to replace the WebViewActivity in favor of a well tested compose screen using nav. label Jun 24, 2026
@TimoPtr
TimoPtr requested a review from jpelgrom June 24, 2026 14:58

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces a typed FrontendTarget destination model to replace raw/nullable “path” usage across launch/navigation flows, and completes more-info deep link handling by supporting the HA 2025.6+ query parameter with a JavaScript fallback for older servers. It also migrates many callers away from WebViewActivity.newInstance toward LaunchActivity-based intents.

Changes:

  • Added FrontendTarget sealed interface and updated LaunchActivity / FrontendRoute / URL resolution APIs to use it.
  • Implemented EntityMoreInfo handling with HA-version gating: URL query param on 2025.6+, JS hass-more-info dispatch fallback otherwise.
  • Updated multiple entry points (widgets, notifications, controls, settings, link handling) and expanded unit test coverage.

Reviewed changes

Copilot reviewed 30 out of 30 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
app/src/test/kotlin/io/homeassistant/companion/android/launch/link/LinkViewModelTest.kt Uses main dispatcher JUnit5 extension for coroutine correctness
app/src/test/kotlin/io/homeassistant/companion/android/launch/LaunchViewModelTest.kt Updates expected routes to use FrontendTarget
app/src/test/kotlin/io/homeassistant/companion/android/frontend/WebViewActionTest.kt Adds coverage for OpenMoreInfo JS generation and escaping
app/src/test/kotlin/io/homeassistant/companion/android/frontend/url/FrontendUrlManagerTest.kt Updates API to target and adds HA-version more-info tests
app/src/test/kotlin/io/homeassistant/companion/android/frontend/navigation/FrontendTargetTest.kt New tests for raw-path parsing/round-tripping
app/src/test/kotlin/io/homeassistant/companion/android/frontend/FrontendViewModelTest.kt Updates URL manager mocks + adds tests for JS more-info fallback behavior
app/src/main/kotlin/io/homeassistant/companion/android/widgets/camera/CameraWidget.kt Migrates widget tap intent to LaunchActivity via FrontendTarget
app/src/main/kotlin/io/homeassistant/companion/android/webview/WebViewActivity.kt Deprecates newInstance to steer callers to LaunchActivity
app/src/main/kotlin/io/homeassistant/companion/android/websocket/WebsocketManager.kt Uses LaunchActivity instead of WebViewActivity for notification intent
app/src/main/kotlin/io/homeassistant/companion/android/util/compose/GlanceExt.kt Switches glance action to build LaunchActivity intent for navigation
app/src/main/kotlin/io/homeassistant/companion/android/settings/shortcuts/views/ManageShortcutsView.kt Uses FrontendTarget parsing/serialization for shortcut entity selection
app/src/main/kotlin/io/homeassistant/companion/android/settings/SettingsFragment.kt Uses FrontendTarget.Default intent for “activate server” CTA
app/src/main/kotlin/io/homeassistant/companion/android/settings/server/ServerSettingsFragment.kt Uses FrontendTarget.Default intent for “activate server” preference
app/src/main/kotlin/io/homeassistant/companion/android/qs/TilePreferenceActivity.kt Routes QS tile setup intent to entity more-info via FrontendTarget
app/src/main/kotlin/io/homeassistant/companion/android/notifications/MessagingManager.kt Migrates notification click routing to FrontendTarget + LaunchActivity
app/src/main/kotlin/io/homeassistant/companion/android/launch/link/LinkActivity.kt Converts raw path deep link to FrontendTarget before launching
app/src/main/kotlin/io/homeassistant/companion/android/launch/LaunchViewModel.kt Switches deep link connect/navigation pipeline to FrontendTarget
app/src/main/kotlin/io/homeassistant/companion/android/launch/LaunchActivityExt.kt Replaces string-path launcher helpers with FrontendTarget variants
app/src/main/kotlin/io/homeassistant/companion/android/launch/LaunchActivity.kt Updates DeepLink.NavigateTo to carry a FrontendTarget
app/src/main/kotlin/io/homeassistant/companion/android/frontend/WebViewAction.kt Adds OpenMoreInfo action for older-server fallback
app/src/main/kotlin/io/homeassistant/companion/android/frontend/url/UrlLoadResult.kt Extends Success with moreInfoEntityId for JS fallback signaling
app/src/main/kotlin/io/homeassistant/companion/android/frontend/url/FrontendUrlManager.kt Introduces target API + HA-version gated more-info URL building
app/src/main/kotlin/io/homeassistant/companion/android/frontend/navigation/FrontendTarget.kt New typed destination model + raw-path mapping helpers
app/src/main/kotlin/io/homeassistant/companion/android/frontend/navigation/FrontendNavigation.kt Stores route as raw path (perf) but exposes typed target
app/src/main/kotlin/io/homeassistant/companion/android/frontend/FrontendViewState.kt Replaces path with FrontendTarget in view states
app/src/main/kotlin/io/homeassistant/companion/android/frontend/FrontendViewModel.kt Tracks pending JS more-info fallback and emits OpenMoreInfo on page finish
app/src/main/kotlin/io/homeassistant/companion/android/controls/HaControlsPanelActivity.kt Removes WebViewActivity path and always routes via LaunchActivity + FrontendTarget
app/src/main/kotlin/io/homeassistant/companion/android/controls/HaControl.kt Updates control PendingIntent to use LaunchActivity + EntityMoreInfo target
app/src/main/kotlin/io/homeassistant/companion/android/assist/AssistActivity.kt Migrates internal navigation to use FrontendTarget.Path via launcher helper

Comment thread app/src/main/kotlin/io/homeassistant/companion/android/util/compose/GlanceExt.kt Outdated
Comment on lines +78 to 81
// Only consume the target when a URL was actually loaded with it
if (urlState is UrlState.HasUrl) {
pathConsumed = true
targetConsumed = true
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I think this is already the behavior we have today.

Comment on lines +193 to +197
private fun moreInfoScript(entityId: String): String {
val entityIdJson = Json.encodeToString(entityId)
return """document.querySelector("home-assistant")""" +
""".dispatchEvent(new CustomEvent("hass-more-info", { detail: { entityId: $entityIdJson }}))"""
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@jpelgrom wdyt?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It's a fallback and has been pretty reliable as far as I'm aware, so I wouldn't change it now. It is only a JS error you'd get, not an app crash, right?

Comment on lines 891 to 893
is UrlLoadResult.Success -> {
pendingMoreInfoEntityId = result.moreInfoEntityId
_viewState.update {
@TimoPtr
TimoPtr force-pushed the feature/more-info_deep-link branch from bf2969f to 8c88dd9 Compare June 25, 2026 11:26
@TimoPtr
TimoPtr requested a review from Copilot June 25, 2026 12:01

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 30 out of 30 changed files in this pull request and generated 5 comments.

Comment thread app/src/main/kotlin/io/homeassistant/companion/android/util/compose/GlanceExt.kt Outdated
Comment on lines +69 to 81
var targetConsumed = false
serverManager.connectionStateProvider(actualServerId).urlFlow().collect { urlState ->
val currentPath = if (pathConsumed) null else path
val currentTarget = if (targetConsumed) FrontendTarget.Default else target

val result = handleUrlState(
serverId = actualServerId,
urlState = urlState,
path = currentPath,
target = currentTarget,
)
// Only consume the path when a URL was actually loaded with it
// Only consume the target when a URL was actually loaded with it
if (urlState is UrlState.HasUrl) {
pathConsumed = true
targetConsumed = true
}

@jpelgrom jpelgrom left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Sorry for the delay. Reviewed again while also considering the next PR and changes almost all look good, just one issue found!

@TimoPtr
TimoPtr force-pushed the feature/more-info_deep-link branch from 60e840c to 406524a Compare July 8, 2026 09:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla-signed WebViewActivity replacement Ongoing work to replace the WebViewActivity in favor of a well tested compose screen using nav.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants