LinkHandler better management of params in deep link URI - #7276
Conversation
| } | ||
|
|
||
| @Test | ||
| fun `Given navigate deep link with a percent-encoded query in the path when invoking handleLink then it is kept encoded`() = runTest { |
There was a problem hiding this comment.
Users that entered the beta 2026.7.4 and 7.5 with % in their shortcut will needs to open back the shortcut and update them manually. I didn't want to include a auto heal there that would increase complexity even more the logic.
There was a problem hiding this comment.
Pull request overview
Fixes shortcut/deep-link URI handling so frontend query/fragment parameters (notably ?kiosk) survive round-trips through homeassistant://navigate links, aligning with the FrontendScreen migration behavior.
Changes:
- Build
homeassistant://navigatedeep links by splitting path/query/fragment components so queries don’t get percent-encoded into the path. - When parsing navigate links, reconstruct the frontend raw path from encoded components while dropping app-only
server/server_idparameters. - Add round-trip tests covering query, fragment, encoding preservation, and absolute URL cases.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| app/src/main/kotlin/io/homeassistant/companion/android/launch/link/LinkHandler.kt | Reworks navigate deep link build/parse to preserve query/fragment and strip server-selection params from the forwarded frontend path. |
| app/src/test/kotlin/io/homeassistant/companion/android/launch/link/LinkHandlerTest.kt | Updates existing expectations and adds coverage for query/fragment round-trips and encoding edge cases. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (2)
app/src/main/kotlin/io/homeassistant/companion/android/launch/link/LinkHandler.kt:62
isValidFrontendRawPathcurrently only compares againstUri.encode(...)while allowing%to pass through. This can return true for inputs with invalid percent-escapes (e.g."...%2G..."or a lone%), but those will fail later when parsing viajava.net.URI(seeUrlUtil.handle) and may also throw when usingUri.Builderencoded setters. Consider validating the rawPath is syntactically parseable as a URI in addition to the encoding check.
internal fun isValidFrontendRawPath(rawPath: String): Boolean =
rawPath == Uri.encode(rawPath, "$QUERY_FRAGMENT_ALLOWED_CHARS#")
app/src/test/kotlin/io/homeassistant/companion/android/launch/link/LinkHandlerTest.kt:300
- Consider extending this validation test set with a case for invalid percent-escapes (e.g.
%2Gor a trailing%). These currently pass theUri.encodeequality check when%is allowed, but will fail when parsed as ajava.net.URIlater.
fun `Given compliant and non-compliant raw paths when validating then only compliant ones pass`() {
assertTrue(isValidFrontendRawPath("lovelace/dashboard-1?kiosk&edit=1#section"))
assertTrue(isValidFrontendRawPath("dashboard/my%20room"))
assertFalse(isValidFrontendRawPath("lovelace/my room"))
assertFalse(isValidFrontendRawPath("lovelace/café"))
}
|
|
||
| if (viewModel.shortcuts[i].type.value == "lovelace") { | ||
| val path = viewModel.shortcuts[i].path.value | ||
| val pathValid = path.isEmpty() || isValidFrontendRawPath(path) |
There was a problem hiding this comment.
If invalid characters are encoded, why disallow them here? If I enter a URL with an invalid character like a space in it in my browser it also encodes it (maybe not in the address bar but it is if you check developer tools), I'd think expecting the app to do the same is valid.
There was a problem hiding this comment.
Most of browser these day capture that and make a search request instead of encoding I think. I think it's better to be strict here, since reloading then after might show the encoded version.
There was a problem hiding this comment.
Testing in Firefox and Chrome and it replaces spaces with %20 if it's after the TLD. If it's in the TLD part it does suggest searching first.
I do agree with the rationale that it might change after reloading from database so it should be avoided, so OK for restricting it.
Summary
Fixes #7263
Shortcuts store their destination in a
homeassistant://navigatedeep link, and the builderpercent-encoded the path's query into the path itself (
?kioskbecame%3Fkiosk), so the frontendnever received it. Introduced with the FrontendScreen migration, beta only.
server_id/serverparameters instead of forwarding the whole deep link string.Updated the UI of the shortcut edition to make sure the link is a valid URL to use (does not contains space for instance).
Checklist
Select exactly one option that describes AI usage in this contribution:
Any other notes
I'm always kind of scared when messing with URL encoding/decoding and hopefully I didn't miss anything. I spent more time challenging Claude on this than fixing the issue itself.