Skip to content

App: opt-in Network setting for QEMU (declares ACCESS_NETWORK_STATE, off by default) - #148

Merged
dylanneve1 merged 2 commits into
mainfrom
app/network-setting
Nov 8, 2026
Merged

dylanneve1 merged 2 commits into
mainfrom
app/network-setting

Conversation

@dylanneve1

Copy link
Copy Markdown
Collaborator

The app side of networking milestone 2 (docs/NETWORKING.md).

What it does:

  • Settings › Advanced › Network (QEMU), per install, off by default (qemu_network in the install list; lists written before it read as off).
  • Off: the QEMU command line is unchanged, with the inferno uplink on the unix socket and no -netdev. QemuCommandTest compares it with a hand-written copy of the old command line. That test passed against main's QemuCommand.build before any change.
  • On: normal boots get -netdev user,id=n0 and usb-uplink-type=net,usb-uplink-addr=n0. Restore boots (a ramdisk= in vm.properties) always keep the inferno uplink. I left out hostfwd (it would open a listening TCP port on the phone); it can be added when something needs SSH.
  • DNS: with the setting on, QemuNet.Resolver writes the default network's LinkProperties.getDnsServers() to files/run/<id>/resolv.conf (nameserver ... lines, %ifname on link-local IPv6). It replaces the file with a rename when the network changes and deletes it when there is no server. QEMU gets the path in SLIRP_RESOLV_CONF, in the child's environment or via Os.setenv in the :vm process. This is the interface of PR 146 (Android build: enable libslirp (-netdev user) and fix DNS on Android #82, libslirp in the Android build).
  • Status card: "Network: off", "Network: waiting for guest", "Network: guest has 10.0.2.15" while a QEMU VM runs, and "Network: off for restore boots" for a restore boot with the setting on. The connected state comes from Inferno's usb-net-uplink: guest reports network connected line. The address comes from slirp's info usernet on the monitor, polled every 3 s until it is found.
  • Manifest: adds ACCESS_NETWORK_STATE. INTERNET was already declared for AVF's Network setting; its comment now covers both.
  • Docs: a PHONE-QUICKSTART "Network (QEMU)" section and settings-table row, ETHICS point 7 and a README paragraph ("doesn't use the network unless you turn Network on"), and a "done in the app" note in NETWORKING.md.
  • Refactors: AppPaths has a constructor from plain directories so the command line can be tested on the JVM; existing AppPaths(ctx, id) callers are unchanged. InstallMigration.seen is now built from the legacy keys alone. With a 13th key, org.json's JVM HashMap reorders, which broke InstallMigrationTest (on Android, where org.json keeps insertion order, the string is the same as before).

Depends on PR 146 for the network to work: without libslirp, QEMU with the setting on exits at once on -netdev user. With the setting off, nothing depends on it, so this can land before or after PR 146.

The AVF backend and native/build-android.sh are untouched.

Tested:

  • ./gradlew lint testDebugUnitTest locally: 42 tests pass (8 new in QemuCommandTest), and lint reports only warnings that were already there.
  • Emulator: see the comment below for results.

Not tested (left for Dylan, needs a Pixel 10 and PR 146):

  • With the setting on, iOS 14 gets a lease and Safari loads a page.
  • With it off, nothing opens an AF_INET socket during a full boot (ss -tuanp / lsof -i).
  • The status line reaching "guest has 10.0.2.15" (needs a booting guest with the network).

Closes #83

Settings > Advanced > Network (QEMU), per install. Off, the QEMU command
line is the one from before: the inferno uplink on the unix socket and no
-netdev (QemuCommandTest compares it with the old command line). On, a
normal boot gets -netdev user,id=n0 and
usb-uplink-type=net,usb-uplink-addr=n0; restore boots (a ramdisk in
vm.properties) always keep the inferno uplink.

With the setting on, the default network's DNS servers from LinkProperties
go to files/run/<id>/resolv.conf, replaced atomically when they change, and
QEMU gets its path in SLIRP_RESOLV_CONF (the interface of the libslirp DNS
fix, #82). The status card shows "Network: off / waiting for guest / guest
has 10.0.2.15", from Inferno's usb-net-uplink link line and slirp's
info usernet.

Declares ACCESS_NETWORK_STATE (INTERNET was already declared for AVF's
Network setting). README, ETHICS and PHONE-QUICKSTART now say the app
doesn't use the network unless Network is turned on.

AppPaths gets a constructor from plain directories so the command line can
be unit-tested; the install fingerprint (InstallMigration.seen) is built
from the legacy keys alone so a new per-install key can't reorder it.
@dylanneve1

Copy link
Copy Markdown
Collaborator Author

Emulator check (shared AVD "iop", sdk_gphone64_arm64), with this PR's CI APK installed fresh after an uninstall:

  • dumpsys package: INTERNET and ACCESS_NETWORK_STATE are both declared and granted.
  • Settings › Advanced shows "Network (QEMU)", off on a fresh install. Turning it on writes "qemu_network":true to installs.xml straight away, and it's still on after a force-stop and relaunch.
  • I used a placeholder VM folder: zero-filled files, plus hand-made DER headers so the IMG4 checks pass. There are no Apple files in it. QEMU builds its command line from it, then crashes on the contents.
    • Setting off: files/run/1/last_run.txt shows -M t8030,...,kaslr-off=true,usb-uplink-type=inferno,usb-uplink-addr=unix:.../files/run/1/usb-uplink.sock, with no -netdev and no network: line in the output.
    • Setting on: the output starts with network: on (slirp behind the guest's USB link) and network: DNS through fec0::3, 10.0.2.3, 10.0.2.4, 10.0.2.5 (the emulator's own DNS servers, from LinkProperties). The command line has usb-uplink-type=net,usb-uplink-addr=n0 and -netdev user,id=n0. QEMU then exits with -netdev user,id=n0: network backend 'user' is not compiled into this binary, which is expected until PR 146 is in. resolv.conf was removed when QEMU exited.
  • I didn't see the status line live: QEMU exited too fast with the placeholder files. Its text is covered by QemuCommandTest.statusLine.

Not done here, so left for Dylan: the Pixel 10 test with PR 146 (a lease, and Safari loading a page with the setting on), and ss/lsof during a real boot with it off.

@dylanneve1
dylanneve1 merged commit 598ca8f into main Nov 8, 2026
3 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

App: opt-in Network setting (declares INTERNET, off by default)

2 participants