mirror of
https://github.com/saphid/frame-control.git
synced 2026-10-06 08:00:32 +02:00
- Anonymous PostHog analytics (ui/frame_telemetry.py): usage on by default after a first-run notice; compatibility results and error details opt-in, offered together by the notice's "Share more to help fix problems" button. Random id, no person profiles or GeoIP, scrubbed text, an offline outbox, and "Show what's been sent" in the new Privacy panel. Inert without a project key, from a source checkout, or with DO_NOT_TRACK=1. - APK installs now record install_failed when the APK itself won't install, and offer a 20-second test after installing. Opted-in reports reach the shared database through PostHog and `frame_compat_db.py sync`. - The desktop app updates itself from published releases (app/updater.js): update.json from releases/latest/download, SHA-256 checked, no downgrades; macOS bundle swap, Windows NSIS, Linux AppImage, otherwise the release page. scripts/publish-release.sh publishes a tested draft with its manifest. - Report a problem (header button, Privacy panel, Help menu) files a GitHub issue through the website's feedback API, with a previewed, scrubbed diagnostics snapshot; activity and logs only when asked for. Reviewed by GPT-6 Astra (xhigh, read-only) three times; all findings fixed. Docs: docs/privacy.md, docs/releasing.md. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
134 lines
6.0 KiB
Markdown
134 lines
6.0 KiB
Markdown
# Privacy and analytics
|
|
|
|
Frame Control sends anonymous analytics to [PostHog](https://posthog.com)
|
|
(EU cloud) so the maintainer can see how many people use it, which features
|
|
matter and where installs fail. You choose how much in **Privacy & updates**,
|
|
the last panel on the page. `ui/frame_telemetry.py` is the whole
|
|
implementation.
|
|
|
|
## The three levels
|
|
|
|
| Level | Default | What it sends |
|
|
|---|---|---|
|
|
| Anonymous usage statistics | On, after a notice on first run | The events in the table below |
|
|
| Share compatibility results | Off | Your Android compatibility reports and tests |
|
|
| Send error details | Off | Scrubbed error messages and tracebacks |
|
|
|
|
Nothing is sent until the first-run notice has been shown. The notice's
|
|
**Share more to help fix problems** button turns on the second and third
|
|
levels together. Either can be turned off later. Turning a level off
|
|
deletes that level's events that haven't been sent yet.
|
|
|
|
**Show what's been sent** in the panel lists the last 50 events that left your
|
|
computer, exactly as they were sent.
|
|
|
|
## Anonymous
|
|
|
|
- Events carry a random id, made when Frame Control first runs and kept in
|
|
its data folder (`telemetry/settings.json`). It isn't derived from your
|
|
computer, account or network. To get a new one, delete that file.
|
|
- Events are sent without person profiles (`$process_person_profile: false`)
|
|
and without location lookup (`$geoip_disable: true`). The PostHog project
|
|
is also set to discard client IP addresses.
|
|
- Every event includes the app version, OS name (macOS, Windows or Linux),
|
|
CPU architecture and Python version.
|
|
|
|
## Usage events
|
|
|
|
| Event | When | Properties besides the common ones |
|
|
|---|---|---|
|
|
| `app_installed` | First run | |
|
|
| `app_updated` | First run of a new version | `from_version` |
|
|
| `app_opened` | At most once a day | |
|
|
| `frame_connected` | The first time a SteamOS build is seen | `steamos_build`, `steamos_version` |
|
|
| `tab_viewed` | The first click on each tab in a session | `tab` |
|
|
| `install_finished` | Any install finishes, working or not | `kind` (apk, flatpak, steam, title, web), `ok`, `seconds`, `error_category`, `installer_code`, and see below |
|
|
| `update_offered`, `update_started`, `update_failed` | The update banner | `to_version`, `error_category` |
|
|
|
|
`install_finished` never includes a file name, path or error message. An
|
|
error becomes one category from a fixed list (for example `apk_wrong_abi` or
|
|
`frame_unreachable`), plus Android's own `INSTALL_FAILED_…` code when there
|
|
is one. It names what was installed only when that's already public:
|
|
|
|
- F-Droid catalogue apps: `package`. Never the version, since a local build can reuse a
|
|
catalogue app's package name
|
|
- Flathub apps: `flatpak_id`
|
|
- Steam games: `steam_appid`
|
|
- A sideloaded title: only its runtime (Proton or Linux)
|
|
|
|
Any other APK is sent as `catalog: false`, with no name.
|
|
|
|
## Compatibility results (opt-in)
|
|
|
|
Each report becomes a `compat_report` event with the fields the Report dialog
|
|
shows: package, version, result or rating, your notes, how it was run, and the
|
|
SteamOS and Lepton builds. Before sending:
|
|
|
|
- the notes, app name and version are scrubbed like error messages (see
|
|
below)
|
|
- the APK's source is kept only if it's `F-Droid` or the public host name of
|
|
a download link (`https://example.com/…`). File names, user names,
|
|
passwords, ports, paths, IP addresses and local host names are dropped
|
|
|
|
When you turn this on, reports you made earlier on this computer are shared
|
|
too.
|
|
|
|
The maintainer's `python3 ui/frame_compat_db.py sync` copies these events
|
|
into the compatibility database, marked `via=community…`. It takes at most
|
|
30 per reporter per day.
|
|
|
|
## Error details (opt-in)
|
|
|
|
`$exception` events carry an error message, the Frame Control file, line and
|
|
function it came from, and the request that failed (for example
|
|
`POST /api/android install`). Before anything is sent, the message is
|
|
scrubbed:
|
|
|
|
- your home folder becomes `~`, and any user name becomes `<user>`
|
|
- IP and MAC addresses, email addresses, `.local`, `.lan` and Tailscale host
|
|
names, Steam ids, SSH and PEM keys, API tokens and long hex strings are
|
|
replaced
|
|
- URLs are cut down to their scheme and a public host name, or `<url>`. User
|
|
names, passwords, ports, paths and queries are dropped
|
|
- `token=`, `key=`, `password=` and similar values are replaced
|
|
|
|
The same error is sent at most once every 10 minutes.
|
|
|
|
## Report a problem
|
|
|
|
**Report a problem** is the warning-sign button in the header, also in the
|
|
Privacy panel and under **Help → Report a Problem…**. It files a public issue
|
|
on [GitHub](https://github.com/saphid/frame-control/issues) through the
|
|
website's feedback service, so no GitHub account is needed. It works whatever
|
|
the analytics settings are, because the person sends it deliberately.
|
|
|
|
With **Include diagnostics** ticked (the default), the report adds:
|
|
|
|
- the app version and whether it's a built app
|
|
- the OS, its release and CPU, and the Python version
|
|
- the Frame's SteamOS build, if it has connected since the app started
|
|
- which analytics levels are on
|
|
|
|
**Also include recent activity and the server log** is off by default,
|
|
because those lines can name files and apps. When ticked, it adds the newest
|
|
Activity lines and server log lines, without the request lines.
|
|
|
|
Everything is scrubbed like error details and limited to what fits in the
|
|
issue. Environment details are kept first, then the newest lines. **Show
|
|
exactly what's included** shows the snapshot that will be sent, and later
|
|
activity isn't added to it. If the service can't be reached, the dialog offers
|
|
**Copy report** and **Open on GitHub instead**, a prefilled issue.
|
|
|
|
## Turning it all off
|
|
|
|
Untick the boxes, or set `DO_NOT_TRACK=1` or `FRAME_CONTROL_TELEMETRY=0` in
|
|
the environment that starts Frame Control. A copy run from a source checkout
|
|
never sends anything unless `FRAME_CONTROL_TELEMETRY=1` is set.
|
|
|
|
## Update checks
|
|
|
|
The desktop app asks GitHub for the latest release shortly after starting,
|
|
then every 6 hours (`api.github.com/repos/saphid/frame-control/releases/latest`).
|
|
That request carries no id. To stop it, set
|
|
`FRAME_CONTROL_NO_UPDATE_CHECK=1`. See [releasing.md](releasing.md).
|