Skip to content
KNOOP edited this page Jun 23, 2026 · 5 revisions

Browser

The built-in browser lets you display web pages inside Ava, such as Home Assistant dashboards. It supports two render engines: System WebView and GeckoView.


Overview

The browser is a full-screen overlay that can display any web content on top of Ava.

Main Uses:

  • Display Home Assistant dashboards
  • Display custom control panels
  • Display information websites
  • Kiosk mode for old devices

Ava Browser vs Other Kiosk Browsers

Ava's browser is not a standalone kiosk browser app. It is a Service-based overlay renderer that runs inside the same process as the voice satellite, using SYSTEM_ALERT_WINDOW to draw web content on top of any Android UI. This architectural difference has significant implications.

Architecture Comparison

Aspect Ava Fully Kiosk WallPanel
Rendering layer SYSTEM_ALERT_WINDOW overlay (Service) Full-screen Activity Full-screen Activity
Process model Runs inside voice satellite process Standalone process Standalone process
Coexistence with voice Native, same process Separate app, no voice Separate app, no voice
Overlay z-order control OverlayZOrderCoordinator manages all overlays N/A (single layer) N/A (single layer)
Lifecycle Persists across app backgrounding, hide/show without destroying renderer Activity lifecycle, renderer destroyed on background Activity lifecycle
Communication with HA ESPHome protocol (native, binary, encrypted) REST API (HTTP polling) MQTT or HTTP
Latency Sub-100ms (persistent TCP + protobuf) 1-5s (HTTP polling interval) 1-5s (MQTT/HTTP polling)

Why Ava's Architecture is Better for HA Dashboards

1. Overlay vs Activity

Fully Kiosk and WallPanel use a full-screen Activity as their rendering surface. This means:

  • The browser takes over the entire screen. No other UI can coexist.
  • Backgrounding the app destroys the WebView renderer. Returning requires a full page reload.
  • Switching between browser and other features requires app switching, not layer switching.

Ava uses WindowManager.addView() with TYPE_APPLICATION_OVERLAY inside a Service. This means:

  • The browser is a layer, not the whole screen. Notification scenes, floating windows, and the wake ripple can appear on top of the browser without destroying it.
  • Hiding the browser does not destroy the renderer. The WebView stays alive in the background. Showing it again is instant, no page reload.
  • The voice satellite, browser, notification overlay, and floating windows all run in one process with coordinated z-order. No IPC, no app switching.

2. ESPHome Protocol vs REST/MQTT Polling

Fully Kiosk communicates with HA via a REST API. HA polls the device every 30 seconds by default. Commands from HA to the device are also polled, adding latency.

WallPanel uses MQTT or HTTP, both polling-based.

Ava uses the ESPHome protocol over a persistent TCP connection with protobuf encoding:

  • Real-time push: HA pushes state changes to Ava instantly. No polling delay.
  • Real-time commands: HA sends browser commands (reload, eval JS, navigate) and they execute in milliseconds.
  • Binary protocol: Protobuf is compact and fast. No JSON parsing overhead.
  • Encrypted: The ESPHome native API supports encryption. REST and MQTT are typically plaintext on LAN.
  • Single integration: Ava appears as one ESPHome device in HA with all entities (browser, sensors, switches, media player) in one place. Fully Kiosk requires a separate integration setup with IP and password.

3. Dual Engine Strategy

Feature Ava Fully Kiosk WallPanel
Default engine System WebView (Chromium) System WebView System WebView
Fallback engine GeckoView pack (separate APK) None None
Old device support Install Gecko pack for modern engine Stuck with old WebView Stuck with old WebView
Engine update Update Gecko pack independently Update via Play Store (may not work on old devices) Update via Play Store

On Android 5-7 devices, the system WebView is often outdated or cannot be updated (no Play Services). Fully Kiosk and WallPanel have no solution for this, their dashboards may fail to render modern CSS/JS.

Ava solves this with a separate GeckoView engine pack (com.example.ava.gecko). The Gecko engine is bundled in the pack and updated independently of the system. On Android 7 kiosk devices, Ava automatically grants the Gecko pack overlay permission and adds it to the vendor kill-list via root/Shizuku.

4. Dark Mode Sync

Feature Ava Fully Kiosk WallPanel
HA theme to browser Bidirectional, real-time via JS bridge One-way (HA CSS media query) One-way (HA CSS media query)
Browser theme to HA Yes, pushes dark mode state back to HA No No
Feedback loop prevention 2-second debounce with suppression flags N/A N/A
Theme override Ava can override HA theme or follow it Follows system only Follows system only

Ava injects 313 lines of JavaScript (BrowserDarkModeScripts.kt) that:

  • Reads ha.hass.themes.darkMode from the HA frontend
  • Subscribes to themes_updated events
  • Applies the theme to document.documentElement CSS variables
  • Pushes theme changes back to Ava's native DarkModeManager
  • Ava then syncs to HA's browser_display entity

This is a true bidirectional sync. Change the theme in HA, the browser follows instantly. Change it in Ava, HA follows. Fully Kiosk and WallPanel can only follow the system dark mode setting.

5. Remote Command Execution

Command Ava Fully Kiosk WallPanel
Navigate to URL Yes (text entity, instant) Yes (REST, polled) Yes (MQTT/HTTP, polled)
Reload page Yes (instant) Yes (polled) Yes (polled)
Execute JS Yes (instant, eval command) No No
Clear cache Yes (instant) Yes (polled) Yes (polled)
Set brightness Yes (instant) Yes (polled) Yes (polled)
Set volume Yes (instant) Yes (polled) Yes (polled)
Fill form field Yes (instant, fillInput with CSS selector) No No
Extract page content Yes (instant, Readability.js) No No
Show/hide browser Yes (switch entity, instant, no reload) Yes (brings app to foreground, reloads) Yes (MQTT, reloads)

The eval command is particularly powerful. You can inject any JavaScript into the dashboard from HA:

# Inject a cherry blossom animation
service: text.set_value
target:
  entity_id: text.your_device_name_browser_command
data:
  value: '{"eval": "document.body.style.animation = ..."}'

Fully Kiosk and WallPanel cannot execute JavaScript on the page. You are limited to the commands they hardcoded.

6. URL Sync Back to HA

Feature Ava Fully Kiosk WallPanel
Sync current URL to HA Yes, automatic via browser_display entity Yes, via REST sensor (polled) Yes, via MQTT (polled)
Latency Instant (push) 30s (poll) 5-30s (poll)
URL normalization Handles localhost, .local, IP addresses None None

Ava normalizes URLs before syncing (adds http:// for localhost/.local/IP, https:// for everything else) to avoid HA storing broken URLs.

7. Overlay Coexistence

This is where Ava's architecture truly shines. On a single device, Ava can simultaneously display:

Layer Z-Order Can coexist with browser?
Browser (WebView) Base overlay Yes (it is the base)
Notification scene Above browser Yes, appears on top
Floating clock Above browser Yes, appears on top
Vinyl cover Above browser Yes, appears on top
Weather overlay Above browser Yes, appears on top
Quick Entity panel Above browser Yes, appears on top
Wake ripple Above browser Yes, appears on top
Screensaver (web/image) Above browser Yes, replaces browser view

With Fully Kiosk or WallPanel, you get one layer. If you want a clock overlay, you need a separate app. If you want a notification popup, you need a separate app. Each app switch destroys and reloads the browser.

Ava's OverlayZOrderCoordinator manages all overlay layers in one process. When a notification scene appears, it slides in on top of the browser. When it dismisses, the browser is still there, unchanged, no reload.

8. Screensaver Architecture

Feature Ava Fully Kiosk WallPanel
Screensaver type Web page, image, Xiaomi wallpaper, clock Image, clock Image, clock
Web screensaver Yes, separate ScreensaverWebViewService No No
Health monitoring 15s load timeout, auto-recovery, 45min preventive refresh None None
Video compatibility Patches HTMLVideoElement.play() for AbortError recovery N/A N/A
Renderer priority IMPORTANT when visible, BOUND when hidden N/A N/A
Proximity wake Yes (via proximity sensor) Motion detection Motion/face detection

Ava's screensaver can display any web page (e.g., a live clock widget, an animated wallpaper, a weather widget) with automatic crash recovery and video playback support. Fully Kiosk and WallPanel only support static images or basic clocks.

9. Tampermonkey / Userscripts

Feature Ava Fully Kiosk WallPanel
Userscript support Yes (full GM API) No No
Script management Built-in UI, install from URL/GreasyFork N/A N/A
GM_xmlhttpRequest Yes (CORS-free) N/A N/A
GM_addStyle Yes N/A N/A
GM_getValue/GM_setValue Yes (persistent) N/A N/A

Ava includes a full userscript manager based on Android-WebMonkey. You can install scripts from GreasyFork directly, or paste a URL. This allows custom CSS/JS injection for any dashboard without modifying HA configuration.

Summary

Criterion Winner
HA integration depth Ava (ESPHome native, instant push)
Rendering on old devices Ava (GeckoView pack)
Overlay coexistence Ava (multi-layer, one process)
Dark mode sync Ava (bidirectional)
Remote JS execution Ava (eval command)
Userscript support Ava (Tampermonkey)
Screensaver flexibility Ava (web page with recovery)
Maintenance Ava (active) vs WallPanel (dead)
Simplicity of setup Fully Kiosk (install and go)
MDM features Fully Kiosk (kiosk lockdown, app management)
Motion detection Fully Kiosk / WallPanel (built-in)

Ava is built for the HA-native kiosk use case: a wall tablet that shows a dashboard, listens for voice commands, displays notification scenes, and syncs everything in real-time. Fully Kiosk is a general-purpose kiosk browser with broader MDM features but no voice, no overlays, no userscripts, and no real-time protocol. WallPanel is unmaintained.

If you need pure kiosk lockdown (restrict apps, disable settings, manage multiple device types), Fully Kiosk is more mature in that area. If you need a HA-integrated dashboard display with voice, notifications, and real-time control, Ava is the better choice.


Render Engines

Ava supports two browser engines:

Engine Description Use Case
System WebView Uses Android system WebView Most devices, lightweight
GeckoView Mozilla Gecko engine pack Old devices with outdated WebView

GeckoView Engine

GeckoView provides a modern browser engine for devices with outdated or missing system WebView.

Setup:

  1. Go to Settings -> Browser
  2. Select GeckoView as render engine
  3. Tap to download the engine pack
  4. When the install dialog appears, tap Install
  5. Wait for installation to complete

Notes:

  • Requires downloading the engine pack (separate APK)
  • Supports arm64-v8a and armeabi-v7a
  • Can check for engine updates and uninstall from settings
  • If the engine pack is not installed, browser falls back to System WebView

Features

Basic Features

Feature Description
Full Screen Web page fills entire screen
Pull to Refresh Pull down to refresh page
JavaScript Full JS support
Local Storage LocalStorage supported
Page Scale Initial zoom (0-500, 0=auto)
Font Size Page font size percentage (50-300)
Touch / Drag Toggle touch and drag interaction

Advanced Features

Feature Description
Render Mode Hardware/software rendering switch
Dark Mode Sync Sync dark mode with Ava and HA dashboard
User Agent Switch browser identity (Android/Desktop/macOS/iOS)
Tampermonkey Userscript support
Browser Sidebar Slide-out menu on the edge
Gesture Navigation Swipe from left edge to go back, swipe left to go forward
Browser Commands Remote control via Home Assistant
Sync URL Sync current browser URL back to HA
Clear Cache Clear browser cache, cookies, and history
Scale Slider Entity Expose a bidirectional scale slider in HA

Settings

Go to Settings -> Browser

Setting Description Default
Render engine System WebView or GeckoView System WebView
Pull to Refresh Allow pull-down to refresh On
Page Scale Initial zoom (0=auto) 0
Font Size Page font size percentage 100
Touch Enabled Allow touch interaction On
Drag Enabled Allow drag operations On
Render Mode Hardware/software rendering Hardware
Follow Dark Mode Sync dark mode with app and HA Off
User Agent Browser identity Default (Android)
Tampermonkey Enable userscript support Off
Browser Sidebar Slide-out menu on the edge Off
Gesture Navigation Swipe to navigate back/forward Off
Settings Button Show gear icon in bottom right Off
Back Key Hide Press back key to hide browser On
Sync Current URL Sync browser URL to HA entity Off
Advanced Control Enable remote browser commands Off
Scale Slider Entity Expose scale slider in HA Off

Render Mode

Mode Description Use Case
Hardware Uses GPU, better performance Most devices
Software Uses CPU, better compatibility Old devices or rendering issues

User Agent Options

Option Description
Default (Android) Standard Android browser
Desktop (Windows) Pretend to be Windows desktop
macOS (Safari) Pretend to be macOS Safari
iOS (iPhone) Pretend to be iPhone Safari

Home Assistant Integration

Recommended Dashboard Setup

Create a dedicated dashboard view for Ava:

# configuration.yaml
lovelace:
  mode: yaml
  dashboards:
    ava-dashboard:
      mode: yaml
      filename: ava_dashboard.yaml
      title: Ava
      icon: mdi:tablet
      show_in_sidebar: false

Hide HA Sidebar and Header

Use custom CSS to hide HA sidebar and header:

ha-sidebar { display: none !important; }
.header { display: none !important; }
home-assistant { --app-drawer-width: 0px; }

Open Web Page

service: text.set_value
target:
  entity_id: text.your_device_name_ha_remote_url
data:
  value: "http://your-ha-address:8123/lovelace/0"

Close Browser

service: text.set_value
target:
  entity_id: text.your_device_name_ha_remote_url
data:
  value: ""

Show/Hide Browser

# Show browser
service: switch.turn_on
target:
  entity_id: switch.your_device_name_browser_display

# Hide browser
service: switch.turn_off
target:
  entity_id: switch.your_device_name_browser_display

Advanced Control (Browser Commands)

After enabling Advanced Control, you can remotely control the browser via Home Assistant services.

action: esphome.xxx_webview_command
data:
  command: 'your command'
Command Format Description
Reload page {"reload": true} Reload current page
Clear cache {"clearCache": true} Clear browser cache
Set brightness {"brightness": 128} Set screen brightness (0-255)
Set volume {"volume": 50} Set volume (0-100)
Execute JS {"eval": "alert('hello')"} Execute JavaScript code
Clear injected {"eval": ""} Clear injected effects

Advanced Features

Tampermonkey (Userscripts)

Ava includes a lightweight userscript manager based on the Android-WebMonkey project.

Supported GM APIs:

  • GM_getValue / GM_setValue
  • GM_addStyle
  • GM_xmlhttpRequest
  • GM_cookie
  • GM_notification

Not Supported:

  • GM_download
  • GM_webRequest
  • unsafeWindow

How to Use:

  1. Go to Settings -> Browser -> Tampermonkey
  2. Enable Tampermonkey
  3. Tap Add Script to install userscripts
  4. Manage installed scripts from the same page

Browser Sidebar

A slide-out menu on the edge of the browser overlay for quick access to features.

Setup:

  1. Go to Settings -> Browser -> Browser Sidebar
  2. Enable sidebar
  3. Choose position (left or right edge)

Using AI to Generate Animation Effects

You can use AI tools to generate custom animation effects (cherry blossoms, snow, stars, etc.) and inject them via the eval command.

Example: Cherry Blossom Animation

service: text.set_value
target:
  entity_id: text.your_device_name_browser_command
data:
  value: '{"eval": "!function(d,b,c,s){d=document,b=d.body,c=d.createElement(\"div\"),s=d.createElement(\"style\"),c.style.cssText=\"position:fixed;top:0;left:0;width:100%;height:100%;z-index:9999;overflow:hidden;pointer-events:none\",s.textContent=\".s{position:absolute;top:-10%;background:linear-gradient(135deg,#fff 20%,#ffb7c5 100%);border-radius:100% 0 120% 0;box-shadow:1px 1px 2px rgba(0,0,0,.1);animation:f linear infinite,w ease-in-out infinite alternate}@keyframes f{0%{opacity:0;transform:translateY(0) rotateX(0) rotateZ(0)}20%{opacity:1}100%{opacity:0;transform:translateY(110vh) rotateX(360deg) rotateZ(720deg)}}@keyframes w{0%{margin-left:-50px}100%{margin-left:50px}}\",d.head.appendChild(s),b.appendChild(c),setInterval(function(p,w,t){p=d.createElement(\"div\"),w=Math.random()*20+8,t=Math.random()*10+6,p.className=\"s\",p.style.cssText=\"left:\"+Math.random()*100+\"%%;width:\"+w+\"px;height:\"+w*1.4+\"px;animation-duration:\"+t+\"s,\"+(Math.random()*4+3)+\"s;animation-delay:-\"+Math.random()*8+\"s\",c.appendChild(p),setTimeout(function(){c.removeChild(p)},t*1e3)},100)}()"}'

Clear Animation Effects

service: text.set_value
target:
  entity_id: text.your_device_name_browser_command
data:
  value: '{"eval": ""}'

Large Instance Dashboard Acceleration

On large Home Assistant instances with thousands of entities, the HA frontend subscribes to every entity at page load (get_states + subscribe_entities with no filter). This firehose makes dashboards slow to load and sluggish, especially on low-powered kiosk devices that only need to display a handful of entities.

HA WebSocket Stripper

HA WebSocket Stripper is an open-source HA add-on that solves this. It is a lightweight reverse proxy that serves your real Lovelace dashboards (real frontend, real cards, Mushroom, button-card, everything) but strips the entity WebSocket down to only what each dashboard actually uses.

How it works:

  • Passes all HTTP traffic straight through to HA (frontend bundles, auth, registries, lovelace config, custom-card resources, untouched)
  • Intercepts only /api/websocket:
    • Rewrites subscribe_entities to include only entity_ids = <allowlist>
    • Filters the get_states response to the allowlist
  • The allowlist is computed from each dashboard's lovelace/config (card tree walk + auto-entities expansion + template entity scan), plus your always_forward and minus your never_forward overrides

Result: A kiosk page that previously downloaded thousands of entity states now downloads only a few dozen, with zero visual difference because it is still the real frontend.

Installation

  1. In HA, go to Settings -> Add-ons -> Add-on Store -> Repositories, add: https://github.com/GabrielGoldsteinAnidea/HA-Websocket-Stripper
  2. Install WebSocket Stripper, open Configuration, set your dashboards:
    dashboards:
      - ava-dashboard
      - home-status
    always_forward: []          # e.g. ["/^sun\\./", "person.you"]
    never_forward: []           # e.g. ["/_battery$/"]
    strip_entities: true
  3. Start the add-on. Browse http://<ha-host>:8099/ava-dashboard (port is remappable under the add-on's Network tab)
  4. Point Ava's browser URL to this proxy address instead of the direct HA URL

Passwordless Kiosk Login

For wall panels and kiosks, you usually want no password prompt. The add-on supports HA's trusted_networks auth provider with two built-in fixes:

  1. host_network: true (built in) so HA sees the real browser IP, not the Docker gateway
  2. X-Forwarded-For normalization (built in) that strips IPv4-mapped IPv6 prefixes

Configure HA's configuration.yaml:

http:
  use_x_forwarded_for: true
  trusted_proxies:
    - 127.0.0.1
    - ::1

homeassistant:
  auth_providers:
    - type: trusted_networks
      trusted_networks:
        - 192.168.1.0/24      # your kiosk's LAN subnet
      allow_bypass_login: true
    - type: homeassistant      # keep this for password login

Then restart HA Core.

Using with Ava

Once the proxy is running, simply set Ava's browser URL to the proxy address:

service: text.set_value
target:
  entity_id: text.your_device_name_ha_remote_url
data:
  value: "http://192.168.1.2:8099/ava-dashboard"

Ava's browser will load the dashboard through the proxy, getting the full real frontend but with a trimmed entity subscription. This is especially useful for:

  • Old Android 5-7 devices with limited CPU and RAM
  • Kiosks displaying a single dashboard with few entities
  • Instances with 1000+ entities where dashboard load time exceeds 10 seconds

FAQ

Web page shows blank?

  1. Check if URL is correct
  2. Check network connection
  3. Try switching render mode (hardware/software)
  4. Try switching to GeckoView engine
  5. Check if HA is accessible

Web page loads slowly?

  1. Check network speed
  2. Simplify dashboard content
  3. Reduce animation effects
  4. Try GeckoView engine on old devices
  5. If you have a large HA instance (thousands of entities), see Large Instance Dashboard Acceleration above

Touch not responding?

  1. Check if Touch Enabled is on
  2. Check overlay permission
  3. Try restarting service
  4. Check if other overlays are blocking

Keyboard doesn't work in browser?

  1. This may be a WebView issue on certain devices
  2. Try switching to GeckoView engine
  3. Check if the system WebView is up to date

Browser doesn't follow dark mode?

  1. Enable Follow Dark Mode in Settings -> Browser
  2. Check if Ava dark mode is enabled
  3. Check if HA dashboard supports dark mode

GeckoView engine install failed?

  1. Check device architecture (arm64-v8a or armeabi-v7a required)
  2. Check network connection
  3. Ensure overlay permission is granted for the engine pack
  4. Try again later if download fails

Back to Home

Clone this wiki locally