Title: Feature request: airplane mode toggle + per-app offline requirement · Issue #141 · MicroPythonOS/MicroPythonOS · GitHub
Open Graph Title: Feature request: airplane mode toggle + per-app offline requirement · Issue #141 · MicroPythonOS/MicroPythonOS
X Title: Feature request: airplane mode toggle + per-app offline requirement · Issue #141 · MicroPythonOS/MicroPythonOS
Description: 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 s...
Open Graph Description: 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 ...
X Description: 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 prob...
Opengraph URL: https://github.com/MicroPythonOS/MicroPythonOS/issues/141
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Feature request: airplane mode toggle + per-app offline requirement","articleBody":"## Summary\n\nMicroPythonOS 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.\n\n## Today's state (as of 0.10.0)\n\n- 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.\n- The Settings → WiFi app lets users scan / connect / forget networks. There's no \"WiFi: Off\" master switch.\n- `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.\n- The only WiFi-off code path that runs in normal use is the power-save in `auto_connect()` (line 381) when initial connection fails.\n- There's no `airplane`, `secure_mode`, `offline_mode`, or `network_disabled` setting anywhere in the codebase.\n- 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.\n\n## What I'd like\n\n### 1. User-facing: airplane mode toggle\n\nA toggle in Settings (probably next to the existing WiFi entry, or as a top-level entry) labelled \\\"Airplane mode\\\" / \\\"Offline\\\". When ON:\n\n- The connectivity manager doesn't auto-connect on boot\n- `WifiService.auto_connect()` no-ops while the toggle is on\n- Any currently-active connection is dropped and `sta.active(False)` is called\n- A visible indicator on the status bar / launcher so the user knows networking is disabled\n- (Future) if/when Bluetooth ships, the same toggle gates the BLE stack\n\nBacking pref: something like `mpos.settings.airplane_mode = true/false`, read by `WifiService.auto_connect` (and the future BLE init).\n\n### 2. Per-app: declare offline requirement in MANIFEST\n\nA new optional manifest field:\n\n```json\n{\n \\\"requires_offline\\\": true\n}\n```\n\nWhen an app with `requires_offline: true` is launched:\n\n- If airplane mode is already on, the app just launches normally.\n- 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.\n- 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.\n\n### 3. Programmatic API for apps\n\nSo a security-conscious app can also enforce \\\"radios down\\\" defensively without relying solely on the manifest gate:\n\n```python\nfrom mpos.net.airplane import AirplaneMode\n\nAirplaneMode.enable() # disables WiFi (and BLE if present)\nAirplaneMode.is_enabled()\nAirplaneMode.disable() # explicit user-consent flow, not auto\n```\n\nA `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.\n\n## Why this matters\n\nLightning 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.\n\n## Implementation sketch\n\n1. Add `airplane_mode` pref to `com.micropythonos.settings`\n2. Gate `WifiService.auto_connect()` and `WifiService.connect()` on it (early return if true, plus immediate `sta.active(False)` if any radio is up)\n3. Add a settings activity row that toggles the pref + a small icon in the launcher / status area\n4. Manifest schema: optional `requires_offline: bool` field in `META-INF/MANIFEST.JSON`. Handle in the launcher / activity-start path.\n5. Public Python API: `mpos.net.airplane.AirplaneMode` with `enable / disable / is_enabled`.\n\nHappy 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.\n\n## Related\n\n- MicroPythonOS#140 — separate decoder bug; not security-related but happened to come up while developing the LP on-chain wallet which prompted thinking about this","author":{"url":"https://github.com/bitcoin3us","@type":"Person","name":"bitcoin3us"},"datePublished":"2026-05-20T15:49:32.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":0},"url":"https://github.com/141/MicroPythonOS/issues/141"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:b4afd70c-eea6-805d-2209-6e76e02dbd64 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | E2FC:102756:2ABD5E5:3BF2E11:6A4F7044 |
| html-safe-nonce | a3edc25b3ff5ae2cb6fd17f69c248c6b003874d41f30864c14871c1d550c4665 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJFMkZDOjEwMjc1NjoyQUJENUU1OjNCRjJFMTE6NkE0RjcwNDQiLCJ2aXNpdG9yX2lkIjoiNzQzNzM3MTczNjEyNTgyOTE4OCIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9 |
| visitor-hmac | eb7fd695b9c34c5c762d10ec8455a2377e4ae687233cc543f231f7792c96e8a7 |
| hovercard-subject-tag | issue:4487925769 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/MicroPythonOS/MicroPythonOS/141/issue_layout |
| twitter:image | https://opengraph.githubassets.com/67656a2808fb514185d020a53688fa7f0b50ff159bfa23300c994dc2b48b23d3/MicroPythonOS/MicroPythonOS/issues/141 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/67656a2808fb514185d020a53688fa7f0b50ff159bfa23300c994dc2b48b23d3/MicroPythonOS/MicroPythonOS/issues/141 |
| og:image:alt | 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 ... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | bitcoin3us |
| hostname | github.com |
| expected-hostname | github.com |
| None | b92d11c0aa4a77d54ef4af1078b6a15fb5a70a215b30c4ecf28889d5a8e656d9 |
| turbo-cache-control | no-preview |
| go-import | github.com/MicroPythonOS/MicroPythonOS git https://github.com/MicroPythonOS/MicroPythonOS.git |
| octolytics-dimension-user_id | 213598128 |
| octolytics-dimension-user_login | MicroPythonOS |
| octolytics-dimension-repository_id | 975472483 |
| octolytics-dimension-repository_nwo | MicroPythonOS/MicroPythonOS |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 975472483 |
| octolytics-dimension-repository_network_root_nwo | MicroPythonOS/MicroPythonOS |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 4b249b445842943ed31549e027f57a8ade9881ed |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width