android icon indicating copy to clipboard operation
android copied to clipboard

Edge to edge support for webviews

Open TimoPtr opened this issue 6 months ago • 13 comments
trafficstars

Summary

Unfortunately I did not manage to properly handle the change of server since I have to enable edge to edge at the beginning of the activity. Furthermore API 36 enable edge to edge by default so we have to handle it. See https://github.com/home-assistant/android/pull/5010 for more details.

Checklist

  • [ ] New or updated tests have been added to cover the changes following the testing guidelines.
  • [x] The code follows the project's code style and best_practices.
  • [x] The changes have been thoroughly tested, and edge cases have been considered.
  • [x] 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.

Screenshots

Left iOS, Right: Android image

Any other notes

I did not manage to force push to the branch in https://github.com/home-assistant/android/pull/5010 after rebasing the branch so I decided to create another branch.

TimoPtr avatar May 22 '25 16:05 TimoPtr

@Gregman-js could you check here? We are also currently making sure the frontend supports for edge to edge is extended to the rest of it https://github.com/home-assistant/frontend/pull/25566

TimoPtr avatar May 22 '25 16:05 TimoPtr

I think this PR should be changed to draft while the frontend is not yet ready to avoid merging it too early (in case the frontend changes don't make it in by 2025.6).

jpelgrom avatar May 22 '25 21:05 jpelgrom

(...) since I have to enable edge to edge at the beginning of the activity [and on] API 36 (...) edge to edge [is enabled] by default so we have to handle it.

And the solution chosen to handle the insets on API 36 generally seems fine to me - adding 'normal'/empty space padding in case of a frontend that does not support it. Why not do the check again after the active server changed? Meaning we're always edge to edge and change the padding in our view as needed.

jpelgrom avatar May 22 '25 21:05 jpelgrom

(...) since I have to enable edge to edge at the beginning of the activity [and on] API 36 (...) edge to edge [is enabled] by default so we have to handle it.

And the solution chosen to handle the insets on API 36 generally seems fine to me - adding 'normal'/empty space padding in case of a frontend that does not support it. Why not do the check again after the active server changed? Meaning we're always edge to edge and change the padding in our view as needed.

I initially wanted to do something by giving a lambda to the applyInsets function but then it becomes a bit more complicated with managing the nav bar and status bar coloring. We would need to also apply and remove coloring depending on the version of the server. I found it a bit too much for the value. If you think it is important we can do it.

TimoPtr avatar May 23 '25 06:05 TimoPtr

I initially wanted to do something by giving a lambda to the applyInsets function but then it becomes a bit more complicated with managing the nav bar and status bar coloring. We would need to also apply and remove coloring depending on the version of the server. I found it a bit too much for the value.

window.statusBarColor and window.navigationBarColor is already deprecated. Maybe it will be easier to replace it with top and bottom Spacer/Box. Then we can hide it to "enable edge to edge" for newer servers. And we can apply background color to this boxes without problem.

Gregman-js avatar May 23 '25 07:05 Gregman-js

window.statusBarColor and window.navigationBarColor is already deprecated. Maybe it will be easier to replace it with top and bottom Spacer/Box. Then we can hide it to "enable edge to edge" for newer servers. And we can apply background color to this boxes without problem.

That could be nice, but may not be as easy on older API versions because of a scrim the system may try to force. Deprecated doesn't mean we should stopping it on older API versions if it works correctly and the behavior isn't the same on all API versions.

jpelgrom avatar May 23 '25 18:05 jpelgrom

The deprecated API is disabled in API 36 so we have to migrate away from it unfortunately even for old version. https://github.com/home-assistant/android/issues/5332

TimoPtr avatar May 23 '25 19:05 TimoPtr

You don't have to migrate away if we can't make it work on older API versions. if (Build.VERSION.SDK_INT => Build.VERSION_CODES.BAKLAVA) { /* or what else the minimum is we can make work with edge to edge, new API */ } else { /* old API }

jpelgrom avatar May 23 '25 19:05 jpelgrom

I've created POC in my repo and this approach hopefully solves all issues: https://github.com/Gregman-js/ha-android/pull/1 I ve tested this in android 13,14,15,16 targeting api 36.

  • Enable enableEdgeToEdge() for all
  • changing active server supported (I think)
  • Add <View> on top and bottom of <Webview> in xml
  • Control above views height with InsetsUtil.kt
if (!serverHandleInsets) {
    statusBarBackground?.updateLayoutParams {
        height = safeInsets.top
    }
    navigationBarBackground?.updateLayoutParams {
        height = safeInsets.bottom
    }
} else {
// evaluateJavascript...
}
  • Support new and old status bar apis Android >= 15 will use Views background color for servers that do not handle edge to edge Android < 15 will use Views background colors and statusBarColor on top for servers that do not handle edge to edge
if (statusBarColor != 0 && !serverHandleInsets) {
    window.statusBarColor = statusBarColor
    binding.statusBarBackground.setBackgroundColor(statusBarColor)
} else {
    Timber.e("Skipping coloring status bar...")
}
if (navigationBarColor != 0 && !serverHandleInsets) {
    window.navigationBarColor = navigationBarColor
    binding.navigationBarBackground.setBackgroundColor(navigationBarColor)
} else {
    Timber.e("Skipping coloring navigation bar...")
}

What do you think?

Gregman-js avatar May 30 '25 10:05 Gregman-js

Could you make your PR to target my branch on the official repo? If your solution works I'm ok with it but we need to make it generic for the 3 places we have a webview

  • AuthenticationFragment
  • MyActivity
  • WebViewActivity

Does that make sense to keep the call to the status bar color if it's deprecated if you provided an alternative solution.

Please remove the modification about the trailing , (I might make a big PR that adds all the , someday)

TimoPtr avatar Jun 03 '25 12:06 TimoPtr

Okay, I will target your PR. I kept status bar color because I wasn't able to test HA on older Androids (emulator, login page doesn't show) in context to @jpelgrom comment:

That could be nice, but may not be as easy on older API versions because of a scrim the system may try to force.

Gregman-js avatar Jun 03 '25 13:06 Gregman-js

I can help if you want an old version of an emulator I did struggle with it too and I've found a workaround and posted it on stackoverflow https://stackoverflow.com/a/79514205/3289338 it helps you find a proper APK of the latest available webview for an old emulator.

TimoPtr avatar Jun 03 '25 17:06 TimoPtr

I created PR here https://github.com/home-assistant/android/pull/5390 for use I will try to test PR with your webview workaround

Gregman-js avatar Jun 04 '25 13:06 Gregman-js

Most of the safe area changes in the frontend are now merged to dev, we should be good to test on android now

ref: https://github.com/home-assistant/frontend/issues/26818

timmo001 avatar Sep 24 '25 09:09 timmo001

@timmo001 I've updated the code of this PR so that if it connects to a server on 2025.10 it is going to send the safe areas.

@jpelgrom I think I've managed to found a way to handle the server switch. But to be fair it's a bit messy to find the right way of doing this into this big class.

I sent to @timmo001 remaining issues, but it is already usable if you want to test.

TimoPtr avatar Oct 10 '25 13:10 TimoPtr