Skip to content

Diagnosing an Android WebView Login Screen With No CSS

Context

Many Android apps embed a WebView to show a login, activation, or SSO screen instead of building it natively — courier/logistics apps, banking apps, and anything using a hosted OAuth flow are common examples. Occasionally that embedded screen renders as raw, unstyled HTML: no CSS, no clickable elements, just plain text and broken layout.

Symptom

  • The embedded screen loads (HTML is present) but has no styling and doesn’t respond to taps.
  • This is the signature of a WebView engine that received the HTML but failed to fetch or parse the CSS/JS — usually because the rendering engine itself is too old for the page, or because loading the linked assets failed outright.

Why the obvious fixes often don’t apply

“Default browser” is an app-launcher preference — which app opens links you tap. It has no relationship to the engine that renders content inside another app’s embedded WebView. Resetting the affected app or clearing WebView’s cache doesn’t change which engine version is installed — it only clears local state. None of these touch the actual variable: the WebView engine version and its eligibility to run.

Two independent failure modes (don’t conflate them)

These two causes produce the same symptom but have nothing to do with each other. Diagnose which one you’re facing before picking a fix.

A. Play Store version ceiling. Google Play caps WebView updates to whatever the device’s Android version / OEM support level allows. On an older or rarely-updated device this ceiling can be years behind current, so the engine can’t render modern CSS. This is genuinely age-related — a device stuck on an old Android version will have an old WebView, full stop.

B. Hidden secondary user profile blocking provider selection. This is not age-related. Android’s WebViewUpdateService requires every candidate WebView provider to be installed and enabled for all user profiles on the device before it’s selectable — not just the active one. Any Android device with a second, OS-managed profile — Secure Folder, a Work Profile, or any OEM app-cloning feature (Samsung Dual Messenger, MIUI Dual Apps, etc.) — will silently create such a hidden profile. A newly installed WebView channel lands only in the primary profile by default, fails the all-users check, and appears in the picker greyed out. This happens identically on a brand-new flagship and on a five-year-old budget phone; it’s a property of having a second profile at all, not of hardware age.

In practice, an old device is more likely to hit both at once (old ceiling forces you to sideload a newer channel, which then trips over the second-profile check) — which is why the two get conflated.

Diagnosis

Confirm the WebView provider state and see the named reason a candidate is invalid, instead of guessing:

adb shell dumpsys webviewupdate

Relevant output:

Current WebView package (name, version): (com.google.android.webview, 87.0.4280.141)
WebView packages:
  Valid package com.google.android.webview (...) is installed/enabled for all users
  Valid package com.google.android.webview.dev (...) is NOT installed/enabled for all users
  Valid package com.google.android.webview.canary (...) is NOT installed/enabled for all users

“NOT installed/enabled for all users” confirms failure mode B. Other reasons (bad signature, missing WebView-library manifest flag, version code too low) point elsewhere and need a different fix.

List the device’s user profiles to find the hidden one:

adb shell pm list users
UserInfo{0:Owner:c13} running
UserInfo{95:DUAL_APP:20001030} running

Any entry besides the primary user (usually 0) is a hidden profile created by a cloning/container feature.

Fix

For failure mode A (version ceiling): install a WebView pre-release channel from Play Store — Beta, Dev, or Canary. These are officially signed by Google, independent of the system WebView package, and carry their own newer Chromium build regardless of the OS-level ceiling on the main package.

For failure mode B (hidden profile blocking selection): enable Developer Options and USB debugging on the phone, connect it to a computer with adb, then:

Install the existing package into the hidden profile (replace 95 with the profile ID from pm list users, and the package name with the one you’re trying to enable):

adb shell pm install-existing --user 95 com.google.android.webview.dev

Verify it now passes the all-users check:

adb shell dumpsys webviewupdate

Set it as the active WebView implementation — try Developer Options → WebView implementation first; if it’s still not selectable, force it:

adb shell cmd webviewupdate set-webview-implementation com.google.android.webview.dev

Reboot and retest.

Notes

Turn off USB debugging after finishing — it’s an attack surface not worth leaving enabled permanently.

If dumpsys webviewupdate reports a different invalidity reason than “NOT installed/enabled for all users,” the fix path above (mode B) doesn’t apply — go back to the dumpsys output and address the specific reason it names.

Last updated on