Skip to content

Feature request: airplane mode toggle + per-app offline requirement #141

@bitcoin3us

Description

@bitcoin3us

Summary

MicroPythonOS currently has no first-class way to disable the radios (WiFi, Bluetooth) on the device, and no way for an app to declare it needs to run with networking off. That's a problem for apps that handle secrets — Bitcoin signers, seed-phrase tools, password managers, anything that should be offline-by-construction. Today the user has no UI affordance to airplane-mode the device, and a sensitive app can't communicate that requirement to the framework.

Today's state (as of 0.10.0)

  • WiFi is auto-started on every boot: mpos/main.py line 318 kicks off WifiService.auto_connect() on a thread, which calls sta.active(True) and reconnects to any saved network.
  • The Settings → WiFi app lets users scan / connect / forget networks. There's no "WiFi: Off" master switch.
  • WifiService.temporarily_disable() / temporarily_enable() exist (mpos/net/wifi_service.py line 391+), but the docstring is explicit that the intent is ADC2 conflict resolution on ESP32-S3 — not security.
  • The only WiFi-off code path that runs in normal use is the power-save in auto_connect() (line 381) when initial connection fails.
  • There's no airplane, secure_mode, offline_mode, or network_disabled setting anywhere in the codebase.
  • Bluetooth: MPOS bundles no BLE code at all. The ESP32-S3 has the silicon, MPOS just doesn't activate it. So today BLE is "off by accident", which is fine, but if BLE support is added later, the same security gap would emerge for it.

What I'd like

1. User-facing: airplane mode toggle

A toggle in Settings (probably next to the existing WiFi entry, or as a top-level entry) labelled "Airplane mode" / "Offline". When ON:

  • The connectivity manager doesn't auto-connect on boot
  • WifiService.auto_connect() no-ops while the toggle is on
  • Any currently-active connection is dropped and sta.active(False) is called
  • A visible indicator on the status bar / launcher so the user knows networking is disabled
  • (Future) if/when Bluetooth ships, the same toggle gates the BLE stack

Backing pref: something like mpos.settings.airplane_mode = true/false, read by WifiService.auto_connect (and the future BLE init).

2. Per-app: declare offline requirement in MANIFEST

A new optional manifest field:

{
  \"requires_offline\": true
}

When an app with requires_offline: true is launched:

  • If airplane mode is already on, the app just launches normally.
  • If airplane mode is OFF, MPOS shows a one-tap dialog: "This app requires offline mode. Enable airplane mode to continue?" → user confirms → airplane mode flips on → app launches.
  • On the app's onPause / onDestroy, airplane mode does NOT automatically flip back. The user explicitly turned it on (with consent), so they explicitly turn it off later — never a surprise reconnect mid-session, never a surprise reconnect after sensitive work.

3. Programmatic API for apps

So a security-conscious app can also enforce "radios down" defensively without relying solely on the manifest gate:

from mpos.net.airplane import AirplaneMode

AirplaneMode.enable()   # disables WiFi (and BLE if present)
AirplaneMode.is_enabled()
AirplaneMode.disable()  # explicit user-consent flow, not auto

A mpos.net.airplane.AirplaneMode class (analogous to WifiService) seems like the right shape — keeps the radio policy in one place rather than scattered across each app.

Why this matters

Lightning Piggy is the obvious nearby example — it's a display-only wallet so WiFi-on is fine. But MicroPythonOS could also be a great target for hardware-wallet-style apps: a Nostr signer, a BIP-32 cold storage viewer, a secp256k1 PSBT signer, a passphrase manager. All of those want "radios off" as a foundational property, not as something each app re-implements with WifiService.temporarily_disable() (a private API meant for ADC2). Without an airplane-mode primitive, MPOS is implicitly an "online-only" OS.

Implementation sketch

  1. Add airplane_mode pref to com.micropythonos.settings
  2. Gate WifiService.auto_connect() and WifiService.connect() on it (early return if true, plus immediate sta.active(False) if any radio is up)
  3. Add a settings activity row that toggles the pref + a small icon in the launcher / status area
  4. Manifest schema: optional requires_offline: bool field in META-INF/MANIFEST.JSON. Handle in the launcher / activity-start path.
  5. Public Python API: mpos.net.airplane.AirplaneMode with enable / disable / is_enabled.

Happy to take a first pass at this if there's interest — would prefer to align on the API shape first so we don't end up with two competing surfaces.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions