From ac60fb060414261935ac5e158b26b34e211e1e06 Mon Sep 17 00:00:00 2001 From: cirakg Date: Sun, 18 Oct 2026 23:44:18 +0200 Subject: feat(spike): add the M1 settings spike app and make targets A separate throwaway app (own app ID, no permissions) that shows what the Garmin Connect app delivers per settings field and writes values back, to measure the undocumented settings limits on the real phone and watch. Includes length-marked test strings, `make spike` / `make spike-sim`, `make vectors`, and step-by-step instructions in docs/SETTINGS_SPIKE.md. Co-Authored-By: Claude Opus 5.5 --- docs/SETTINGS_SPIKE.md | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 docs/SETTINGS_SPIKE.md (limited to 'docs/SETTINGS_SPIKE.md') diff --git a/docs/SETTINGS_SPIKE.md b/docs/SETTINGS_SPIKE.md new file mode 100644 index 0000000..340670a --- /dev/null +++ b/docs/SETTINGS_SPIKE.md @@ -0,0 +1,92 @@ + +# Settings spike (M1) + +Garmin doesn't document how long a text setting may be, which characters the Garmin Connect app accepts, or whether values written by the watch show up on the phone. The inbox and import design (README sections 10 and 11) depends on those answers, so this milestone measures them with a small throwaway app, **Settings Spike**, on your Android phone and Forerunner 70. + +It takes about 30 minutes. Everything uses fake test strings; never paste a real secret here. + +## What the spike app does + +- Its settings have eight text fields with no length limit, one password field, a read-only status field, a switch, a list, a number and a long number. +- On the watch it shows, for each text field: the length in characters and bytes, the first 12 and last 8 characters, and which of `& < > \ " { } %` and non-ASCII characters arrived. +- Each time you save settings while the app is open, it counts the change, writes `seen N chars at HH:MM:SS, change #K` into the read-only status field, and clears the password field. That tests whether the phone shows values the watch wrote. +- Scroll with UP/DOWN or by swiping; START or a tap jumps back to the top. + +The test strings make cuts obvious: each starts with `N=|`, has a marker `P` every 50 characters, and ends with `END`. If the watch shows a different length or no `END`, the phone app cut the string; the last marker visible tells roughly where. + +## Step 1: build the package (on your computer) + +```sh +make spike +``` + +The file to upload is `build/spike/settings-spike.iq`. The spike has its own app ID, separate from OTP Wallet, so it can be deleted afterwards without affecting the real app. + +## Step 2: a Garmin developer account and the beta upload + +1. Open https://developer.garmin.com/connect-iq/ in a browser and sign in with your normal Garmin account. Accept the Connect IQ developer agreement if asked (the same agreement `make sdk` showed you). +2. Go to the developer dashboard (the "Upload an app" / "My apps" area of the Connect IQ developer site). +3. Upload `build/spike/settings-spike.iq` as a **new app** and tick **Beta App**. Fill in what the form requires (name "Settings Spike", any short description, any category). A beta app is visible only to your account. +4. Wait until the upload shows as available (usually minutes). + +Garmin changes these pages from time to time; if a label differs, look for "beta" in the upload form. + +## Step 3: install it on the Forerunner 70 + +1. On the phone, open the Connect IQ Store app (or Connect IQ inside Garmin Connect) while signed in to the same account. +2. Find **Settings Spike** among your apps (or open the beta's store link from the developer dashboard on the phone) and install it on the Forerunner 70. +3. On the watch, start **Settings Spike** from the apps list. It should show "Settings spike", "Changes seen: 0" and eight empty text fields. + +## Step 4: get the test strings onto the phone + +Copy `spike/settings/test-strings/index.html` to the phone (for example email it to yourself, or copy it over USB) and open it in Chrome. Each string has a **Copy** button that tells you how many characters it copied. The same strings are also in `spike/settings/test-strings/*.txt` (copy only the last line of a file). + +## Step 5: the tests + +Keep the spike app open on the watch for tests A to H, except where a test says otherwise. Open the settings on the phone through Garmin Connect: the Forerunner 70, then Connect IQ apps (or Activities & Apps), then Settings Spike, then Settings. Save after each change and read the watch. + +| Test | What to do | What to write down | +| --- | --- | --- | +| A. One long field | Paste the 100-character string into Text 1, save. Repeat with 255, 256, 500, 800, 801, 1000, 2000, 4000 and 8000 (always Text 1). | The longest length that arrives complete (length matches and ends with `END`). For the first one that fails: does the phone refuse to save, show an error, or cut it silently (then the length the watch shows)? | +| B. Total size | Put the longest string that worked in A into Text 1 to Text 8, save. If that fails, empty fields until it saves. | The largest total ("Total: N chars" on the watch) that saves, and what happens beyond it | +| C. Characters | Paste `special` into Text 2, save. | The "has:" line on the watch, and anything missing compared with the string (especially `&` and `\`) | +| D. Write-back | After any save, close the settings on the phone and open them again. | Does "Status written by the watch" show `seen ... change #N`? Is the password field empty? | +| E. Live changes | With the app open, change one field and save. Then close the app on the watch, change another field, save, and start the app again. | Does "Changes seen" increase while the app is open? After the restart, does the watch show the new value? | +| F. Password field | Type `fake1234` into the password field, save. | Does the watch show "got 8 chars"? When you reopen the settings, is the field masked, empty, or showing the text? | +| G. Timing | Use a stopwatch from tapping Save until the watch screen changes. | Seconds for a short string and for the longest that worked | +| H. Other types | Toggle the switch, pick option C, enter 0 and then 301 as the number, enter 9999999999 as the long number. | Values shown on the watch, and which inputs the phone rejects (and its message) | + +## Results + +Fill this in (or tell me the values and I'll record them). Date, phone model, Garmin Connect app version (Settings, About) and the watch firmware help explain later differences. + +| Item | Result | +| --- | --- | +| Date, phone, Garmin Connect version, watch firmware | | +| A. Longest single field that arrives complete | | +| A. What happens above that (refused / error / cut to N) | | +| B. Largest total across the eight fields | | +| C. Characters that didn't arrive or blocked saving | | +| D. Status written by the watch visible on the phone (yes/no) | | +| D. Password field empty after the watch cleared it (yes/no) | | +| E. Changes arrive while the app is open (yes/no) | | +| E. Changes arrive while the app is closed, seen at next start (yes/no) | | +| F. Password field: arrives on the watch, masked on the phone (yes/no each) | | +| G. Time from Save to the watch updating (short / longest) | | +| H. Phone-side validation of the number fields (message) | | +| Other observations | | + +## How the results feed the design + +- **A and B** set the number and size of the import fields (`impText1` to `impTextN`, README 10.2) and the multi-part import buffer (README 11.2). For example, if one field holds 4000 characters but the total stops at 8000, import uses two or three fields per sync and multi-part import for larger Aegis files. +- **C** decides whether `otpauth://` URIs can be pasted as they are on your phone and whether the parser needs the `;` fallback (README 11.2). +- **D** decides whether status messages and cleared secret fields are visible on the phone. The design works either way (forms are idempotent and results also show on the watch, README 10.3); this tells us which one you'll experience. +- **E and G** decide whether processing on `onSettingsChanged` is enough or whether the app must also process forms at every start (it will do both; this confirms it). +- **F** confirms what the password field protects (on-screen masking only). + +## Cleaning up + +When the results are recorded: uninstall Settings Spike from the watch (Connect IQ Store app or the watch's app settings), and delete the beta from the developer dashboard if you like. The spike's code stays in `spike/settings/` for reference. -- cgit v1.2.3