components/webapps/docs/projects/al-site-settings/registration_and_permissions.md
This document describes how Chromium on Android registers installed web applications (TWAs and WebAPKs) and manages permission delegation between the Android OS and the browser.
To provide a seamless app-like experience, Chrome needs to know which web origins are associated with which installed Android packages. This allows for features like:
InstalledWebappRegistrar: A singleton that handles registration requests
when a TWA is verified or navigated. It deduplicates requests and calls
InstalledWebappDataRegister and PermissionUpdater.InstalledWebappDataRegister: A utility class that manages the storage of
registered web apps in SharedPreferences. It handles the mapping between
Android identifiers and web origins/domains.InstalledWebappBroadcastReceiver: An Android BroadcastReceiver that
listens for package uninstallation or data clearing events and triggers
cleanup in Chrome.PermissionUpdater: A utility class that coordinates updating permissions
(notifications, location) in Chrome when apps are verified or uninstalled.InstalledWebappBridge: The JNI bridge between C++ and Java for
permission decisions.This sequence diagram shows the flow when a user launches or installs a TWA/WebAPK.
sequenceDiagram
autonumber
actor User
participant TWA as TWA App
participant IWR as InstalledWebappRegistrar
participant IWDR as InstalledWebappDataRegister
participant SP as SharedPreferences
Note over User, TWA: User Journey: Install & Launch
User->>TWA: Launches TWA
TWA->>IWR: registerClient(packageName, origin, url)
IWR->>IWDR: registerPackageForOrigin(...)
IWDR->>SP: Store data keyed by PackageName
This sequence diagram shows the flow when an app is uninstalled or its data is cleared.
sequenceDiagram
autonumber
actor User
participant Android as Android OS
participant IWBR as InstalledWebappBroadcastReceiver
participant WAUT as WebApkUninstallTracker
participant CDS as ClearDataStrategy
participant PU as PermissionUpdater
participant IWDR as InstalledWebappDataRegister
participant CDDA as ClearDataDialogActivity
participant BSS as BrowserServicesStore
Note over User, Android: User Journey: Uninstall / Clear Data
User->>Android: Uninstalls App
Android->>IWBR: Broadcast (ACTION_PACKAGE_FULLY_REMOVED)
alt is WebAPK
IWBR->>WAUT: deferRecordWebApkUninstalled(packageName)
end
IWBR->>CDS: execute(packageName)
CDS->>IWDR: getDomains/Origins(packageName)
CDS->>PU: onClientAppUninstalled(origin)
Note over PU: Resets location / updates notifications
CDS->>CDDA: Start Activity (Dialog)
IWBR->>BSS: removeTwaDisclosureAcceptanceForPackage(...)
IWBR->>IWDR: removePackage(packageName)
This diagram shows how permission requests flow from C++ to Java and back via JNI.
sequenceDiagram
autonumber
participant CPP_P as C++ Permission System
participant CPP_B as C++ InstalledWebappBridge
participant J_B as Java InstalledWebappBridge
participant J_PU as Java PermissionUpdater
participant J_NPU as Java NotificationPermissionUpdater
participant J_TWAC as Java TrustedWebActivityClient
participant Android as Android System / TWA
Note over CPP_P, Android: Flow: C++ requests permission decision from TWA
CPP_P->>CPP_B: DecidePermission(...)
CPP_B->>J_B: decidePermission(...) [JNI]
J_B->>J_PU: requestNotificationPermission(...)
J_PU->>J_NPU: requestPermission(...)
J_NPU->>J_TWAC: requestNotificationPermission(...)
J_TWAC->>Android: Query TWA Service / System
Android-->>J_TWAC: Permission Result
J_TWAC-->>J_NPU: Result
J_NPU->>J_B: runPermissionCallback(callback, setting)
J_B->>CPP_B: RunPermissionCallback(...) [JNI]
CPP_B->>CPP_P: Run C++ Callback
org.chromium.chrome.browser.webapps.WebApkActivityCoordinatorInstalledWebappRegistrar.getInstance().registerClient(packageName, origin, storage.getUrl())
during activity setup.org.chromium.chrome.browser.browserservices.ui.trustedwebactivity.TrustedWebActivityCoordinatorInstalledWebappRegistrar.getInstance().registerClient(...) during setup.TrustedWebActivityCoordinator flow on the Chrome side, but
relies on Android's IWebAppService (Mainline module) for the actual
installation on the OS side.org.chromium.chrome.browser.webapps.WebApkActivityCoordinatorPermissionUpdater.onWebApkLaunch(origin, packageName) to check and update
notification permissions on launch (especially for Android T+).InstalledWebappRegistrar.registerClient being called on navigation
to ensure permissions are up to date.For a detailed design of the fix for shared UID and origin deduplication issues, including the migration plan, see design.md.
When a client app is uninstalled, PermissionUpdater.onClientAppUninstalled is
called. It performs the following:
WebAPK uninstalls are often detected by a broadcast receiver when Chrome is not
running. To avoid loading native libraries immediately just to record metrics,
WebApkUninstallTracker defers this work. It stores the uninstalled package
names in SharedPreferences and processes them (recording histograms and UKM)
the next time Chrome is launched and native is loaded.
ClearDataDialogActivity is triggered when an app is uninstalled or its data is
cleared. It doesn't clear data directly but prompts the user and navigates them
to Chrome's Site Settings:
SingleWebsiteSettings
for that origin.AllSiteSettings filtered by the
domains (eTLD+1) associated with the app, allowing the user to clear data for
the relevant scope.