I configure my NixOS box from a versioned file; I want my phone’s home
screen the same way — declared once, applied reproducibly, with no
tapping, dragging or dropping.
Question: on Android 7+ / LineageOS, can a home screen carrying several
screens, app widgets, and PWAs — including self-hosted ones served from
http://localhost — be provisioned declaratively from a
version-controlled config, and at what privilege cost?
Working hypothesis (the target, held fixed for the whole note): a
de-Googled LineageOS — no Google Play Services (GMS) — running a
Launcher3-based launcher — on stock LineageOS that is Trebuchet, a fork
of AOSP’s Launcher31 — and a Chromium-based
browser.
[objective]: on a de-Googled LineageOS (Android 7+, no GMS), can a
home screen — several screens, app widgets and PWAs — be
provisioned declaratively from a versioned file, with no manual
tap/drag, and at what privilege cost?
can the home screen be described in a file?
The first question is whether the workspace is even expressible as
data. It is: AOSP Launcher3 ships an XML parser whose vocabulary maps
one-to-one onto what I want — screens, icons, folders, and widgets at
chosen grid cells.
Relations
support — dialectical · for
Strength
documented observation
Node border/fill = propagated strength, same scale (fill paler).
at what privilege does that file apply?
Expressible is not appliable. The tension is in where the XML comes
from and when it is read: Launcher3 does not read a user file, it
reads a resource baked into a system package, and only once.
Relations
support — dialectical · for
Strength
convergent testimony
documented observation
Node border/fill = propagated strength, same scale (fill paler).
why « add to home screen » is not enough for a PWA
PWAs are the awkward third. The obvious gesture — the browser’s « add
to home screen » — does not yield an installed app on a de-Googled
phone, because the real install (a WebAPK) is minted by a Google
server the phone cannot reach.
Relations
support — dialectical · for
Strength
convergent testimony
documented observation
Node border/fill = propagated strength, same scale (fill paler).
how to install a PWA declaratively
If the browser will not mint the app, the app is built ahead of time,
from a file. A Trusted Web Activity (TWA) wraps the PWA in a thin APK,
and Bubblewrap generates that APK from the site’s web manifest — which
is exactly IaC: config in, installable artifact out.
Relations
support — dialectical · for
Strength
convergent testimony
documented observation
Node border/fill = propagated strength, same scale (fill paler).
One PWA does not fit the TWA path: the self-hosted one, served from
the phone’s own loopback — http://localhost — with no public domain
and no certificate. The browser treats it as a securely-delivered,
trustworthy origin2; the trouble is proving to a
Trusted Web Activity that the app and the site share one owner, when
the site is every device’s own localhost.
Relations
support — dialectical · for
Strength
convergent testimony
documented observation
Node border/fill = propagated strength, same scale (fill paler).
The fix is to stop asking a Trusted Web Activity to trust a site it
structurally cannot verify, and instead ship an app that never runs the
check. The cleanest is our own thin WebView; forking the browser’s
verification or decompiling a prebuilt TWA APK are heavier variants of
the same bypass.
Relations
support — dialectical · for
Strength
convergent testimony
documented observation
Node border/fill = propagated strength, same scale (fill paler).
conclusion
Yes — but as two mechanisms, not one. The launcher layout is
expressible as declarative XML (a file) yet appliable only as a
first-boot system artifact — root or a ROM build, plus a data wipe.
PWAs cannot be installed by the browser without GMS (only a shortcut),
so they take the TWA-from-manifest path: a versioned config compiled
to an APK and adb install-ed. A PWA served from http://localhost is
the exception even to that path — a Trusted Web Activity cannot verify
a loopback origin, so it degrades to a URL-bar Custom Tab
(the localhost case); the reproducible answer there is our own thin
WebView APK, not a TWA.
The no-tap/drag goal is met on both halves; the price is asymmetric —
the PWA half is plain user-space tooling, the launcher half costs
system privilege. See the overview map in the whole argument.
[iac feasible, split path]: home-screen-as-code is feasible on a
de-Googled LineageOS, but along two distinct paths — the launcher
layout as a first-boot system XML (root/ROM + data wipe), and
PWAs as TWA APKs built from a versioned manifest and adb-installed.
The no-tap/drag goal holds; only the launcher half costs system
privilege. A =http://localhost= PWA is the one exception to the TWA
route — it cannot pass Digital Asset Links verification, so it ships
as our own WebView APK instead.
Open questions, each its own note rather than diluting this chain: a
user-space alternative for the launcher half — a third-party launcher
whose backup/restore file can be generated and pushed without root
(Nova, Lawnchair, others) — and exactly which LineageOS Chromium-based
browsers implement the TWA protocol well enough to render a Bubblewrap
APK full-screen.
the whole argument
The overview: the thesis, the two positive results that carry it, and
the privilege cost that qualifies it. It aggregates the chapter blocks
via :argdown-include (each claim is defined once, in its chapter).
Relations
support — dialectical · for
attack — dialectical · against
Strength
convergent testimony
documented observation
Node border/fill = propagated strength, same scale (fill paler).
— LineageOS Trebuchet’s .gitupstream, which records the AOSP repository
it forks (branch lineage-22.2):
Locally-delivered resources such as those with http://127.0.0.1,
http://localhost, and http://*.localhost URLs (for example,
http://dev.whatever.localhost/) are not delivered using HTTPS, but they
can be considered to have been delivered securely because they are on the
same device as the browser. They are therefore potentially trustworthy.