< Back to all hacks

#30 Tier 1.5: Headless Server Mode

Debloat
Problem
SystemUI (70 MB), Phone (42 MB), Media (40 MB), Keychain (35 MB) still running on headless server.
Solution
pm disable via Dirty COW root. Android base 244 -> 196 MB. Total 441 -> 374 MB.
Lesson
SystemUI respawns in degraded mode (~5 MB). WiFi works without these services.

Context

After disabling 51+ user-facing packages with boot-debloat (Hack #26) and the extended pass (Hack #27), dumpsys meminfo still showed four heavyweight system services consuming 187 MB combined. These services exist to provide the phone's interactive UI layer: the status bar, notification shade, lock screen, phone dialer, media scanner, and certificate management. On a headless server that will never display a UI or make phone calls, all of this is dead weight.

The Moto E2 is running as a dedicated PocketClaw gateway. Nobody touches the screen. There is no SIM card. The only interfaces are SSH and HTTP. The question was: can Android function as a WiFi-connected headless server without these core system services?

The answer is yes — with caveats.

Implementation

These disables require Dirty COW root (Hack #34) because they target core Android system packages that adb shell pm disable-user refuses to touch.

# Run from ADB shell after Dirty COW root
# (inside boot-debloat.sh or manually)

# SystemUI — status bar, notification shade, lock screen, recent apps
# 70 MB RSS. Largest single system service.
pm disable com.android.systemui

# Phone / Dialer — telephony stack
# 42 MB RSS. No SIM card, no calls needed.
pm disable com.android.phone

# Media Provider — media scanner, thumbnail generation
# 40 MB RSS. No photos, no music, no videos on this device.
pm disable com.android.providers.media

# Keychain — certificate management for apps
# 35 MB RSS. Gateway uses Node.js TLS with ca-certificates, not Android keychain.
pm disable com.android.keychain

Add to the automated boot-debloat script so they're disabled after every reboot:

# Append to /data/local/tmp/boot-debloat.sh (or stop-daemons.sh)
# These run after Dirty COW grants root

HEADLESS_PACKAGES="
com.android.systemui
com.android.phone
com.android.providers.media
com.android.keychain
"

for pkg in $HEADLESS_PACKAGES; do
  pm disable "$pkg" 2>/dev/null && echo "Disabled: $pkg"
done

Verification

# Verify all four are disabled:
adb shell pm list packages -d | grep -E "systemui|phone|providers.media|keychain"
# Expected:
# package:com.android.systemui
# package:com.android.phone
# package:com.android.keychain
# package:com.android.providers.media

# Check RAM usage before and after:
adb shell dumpsys meminfo | head -20
# Look for "Total RAM" and "Used RAM" lines

# Verify WiFi still works:
adb shell ping -c 3 8.8.8.8
# Expected: 3 packets transmitted, 3 received

# Verify gateway is accessible:
curl -s http://localhost:9000/api/status
# Expected: JSON response (via adb forward tcp:9000 tcp:9000)

# Check SystemUI respawn state:
adb shell ps | grep systemui
# Expected: either absent or running with ~5 MB RSS (degraded mode)

Gotchas

  • SystemUI does NOT stay dead. Android's system_server detects the crash and restarts SystemUI in a degraded fallback mode. The respawned SystemUI uses only ~5 MB RSS instead of the original 70 MB, so the net savings is ~65 MB rather than 70 MB. Trying to kill or disable it repeatedly in a loop is counterproductive — let it respawn in degraded mode
  • Disabling com.android.phone removes ALL telephony: no calls, no SMS, no mobile data. This is fine for a WiFi-only server but means you cannot use the phone as an actual phone until you re-enable it
  • The Media Provider disable breaks the system gallery, camera, and any app that queries content://media/. Since PocketClaw never uses the media content provider, this is harmless
  • Disabling Keychain means Android apps that use the system certificate store for client certificates will fail. Node.js manages its own TLS through OpenSSL and the ca-certificates bundle, so the gateway is unaffected
  • If you need to temporarily use the phone's UI (e.g., to change WiFi settings manually), re-enable SystemUI first: pm enable com.android.systemui. The full UI returns within seconds
  • These disables persist across reboots via package-restrictions.xml in /data/system/users/0/. The Dirty COW root is only needed for the initial disable, not to maintain the state

Result

MetricBeforeAfterSaved
Android base RAM244 MB196 MB48 MB
Total system RAM441 MB374 MB67 MB
SystemUI70 MB~5 MB (degraded)65 MB
Phone/Dialer42 MB0 MB42 MB
Media Provider40 MB0 MB40 MB
Keychain35 MB0 MB35 MB
Gateway boot time~120s~70s42% faster
WiFi connectivityWorkingWorkingNo impact
TelephonyWorkingDisabledExpected