You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/architecture/intents.md
+73-1Lines changed: 73 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -814,6 +814,78 @@ class WiFiActivity(Activity):
814
814
815
815
**Pattern:** Method chaining with `startActivityForResult()` for specialized camera modes.
816
816
817
+
---
818
+
819
+
## Deep Links & URL Handling
820
+
821
+
MicroPythonOS supports opening URLs (e.g., from QR codes) through a deep-link mechanism. The system parses the URL and either opens the App Store on a linked app or dispatches an intent to a third-party URL handler.
822
+
823
+
### Official Store Links
824
+
825
+
QR codes can point directly to an app in the App Store using these link formats:
All three forms are equivalent and case-insensitive (`MPOS://APP/COM.EXAMPLE.PAINT` works too). The link only carries the app's identity — never a download URL — so the App Store resolves it against its trusted catalog.
834
+
835
+
Opening a store link launches the App Store on the linked app's detail page:
- Must look like `scheme://host/...` with a literal host (no wildcards in host).
864
+
- A trailing `*` is the only wildcard allowed and matches any suffix.
865
+
- Patterns matching the official store host (`apps.micropythonos.com`) or the `mpos://` / `microPythonOS://` schemes are reserved for the system and rejected at registration.
866
+
- Matching is a case-insensitive scheme-and-host prefix match.
867
+
868
+
When a URL is opened, the system checks for matching third-party handlers. One match dispatches directly; several open the chooser. No sticky default is set, so a later-installed app is never permanently shadowed.
869
+
870
+
```python
871
+
from mpos.content.deeplink import open_url
872
+
873
+
# Dispatches to the app whose urlPattern matches the URL
874
+
open_url("https://store.acme.example/app/123")
875
+
```
876
+
877
+
### QR Code Integration
878
+
879
+
QR scanners (e.g., the Camera app) can check whether decoded text is a dispatchable link:
880
+
881
+
```python
882
+
from mpos.content.deeplink import open_action_label
883
+
884
+
label = open_action_label(scanned_text)
885
+
if label:
886
+
print(f"Offer action: {label}") # "Open in App Store" or "Open link"
887
+
```
888
+
817
889
## Best Practices
818
890
819
891
### 1. Choose the Right Intent Type
@@ -991,7 +1063,7 @@ MicroPythonOS Intents are inspired by Android's Intent system but simplified for
991
1063
|**Intent Filters**| ✅ Manifest + programmatic | ✅ In manifest | File-type filters in `MANIFEST.JSON`, generic handlers via code |
-**Status codes NOT followed:** 307 (Temporary Redirect), 308 (Permanent Redirect). These are treated as the final response.
87
+
-**Maximum redirects: 1 hop.** The HTTP client (`aiohttp`) makes at most 2 requests per call — the original URL plus one redirect. A chain of 2 or more redirects will fail: the final redirect response body (typically empty) is treated as the download content, resulting in a parse error or corrupt file.
88
+
89
+
!!! warning
90
+
If you need to redirect `https://updates.micropythonos.org/...` to `https://updates.micropythonos.com/...`, ensure the `.com` endpoint responds directly with a 200 — do not chain another redirect. A 2-hop chain (`.org` → `.com` → `.com?__direct=1`) will exhaust the redirect budget.
The default sound is `Coin`. If no buzzer output is available, the notification posts silently. Apps can change the sound programmatically:
79
+
The default sound is `Coin`.
80
+
81
+
On macOS desktop builds the notification buzzer sound is skipped because it was causing `tests/test_graphical_topmenu_drawer.py` to hang on the GitHub test workflow, possibly because the GitHub CI server doesn't have a sound card. It would be better to only skip this on the CI server, or only skip it if there's no sound card.
82
+
83
+
On other platforms, if no buzzer output is available, the notification posts silently. Apps can change the sound programmatically:
Copy file name to clipboardExpand all lines: docs/os-development/automated-testing.md
+25Lines changed: 25 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -63,4 +63,29 @@ To run all unit tests, do:
63
63
./tests/unittest.sh --ondevice # this takes a long time
64
64
```
65
65
66
+
## Test Runner Flags
67
+
68
+
The `test_runner.py` script (used by `unittest.sh` internally) supports these additional flags:
69
+
70
+
| Flag | Description |
71
+
|------|-------------|
72
+
|`--no-install-test-apps`| Skip automatic installation of test apps before on-device runs. By default, `--ondevice` runs call `install_test_apps.sh` automatically. |
73
+
|`--logserial <filename>`| Write raw serial output to a file for debugging communication issues. |
74
+
|`--coverage`| Enable code coverage tracking on desktop builds (requires a coverage build — see `./scripts/build_mpos.sh unix coverage`). |
75
+
|`--coverage-save <file.json>`| Save coverage data to a JSON file for later aggregation or HTML report generation. |
76
+
|`--coverage-load <file.json>`| Load previously saved coverage data to merge with the current run. |
Copy file name to clipboardExpand all lines: docs/os-development/running-on-desktop.md
+10Lines changed: 10 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -112,6 +112,16 @@ Native Windows builds are not supported. [Users report](https://github.com/Micro
112
112
113
113
---
114
114
115
+
## Keyboard shortcuts
116
+
117
+
The desktop emulator supports these keyboard shortcuts:
118
+
119
+
| Shortcut | Action |
120
+
|----------|--------|
121
+
| Ctrl+Shift+S (Cmd+Shift+S on macOS) | Save a screenshot as BMP in the working directory |
122
+
123
+
Screenshots are saved with a timestamped filename like `screenshot-YYYYMMDD-HHMMSS.bmp`. The path is printed to the console so you know exactly where the file was written.
124
+
115
125
## Deploying to hardware
116
126
117
127
Once your app works on desktop, install it on a supported ESP32 device.
0 commit comments