Quiblo wiki

Orientation

Licence and legal posture

Why GPLv3 and not GPLv2 or AGPL, and the position we take on content.

# GPLv3, and why not the alternatives

Quiblo is licensed under the GNU General Public License v3.0 or later. The full, unmodified text is in LICENSE, and every source file carries a header — a rule checked in CI over git ls-files '*.kt' rather than by hand.

Why not GPLv2

The dependency tree — Media3, Compose, all of AndroidX — is Apache-2.0. Apache-2.0 is incompatible with GPLv2 and compatible with GPLv3. That alone settles it. GPLv3 also carries an explicit patent grant and anti-tivoization terms, which satisfy the requirement that the project stay open source through any downstream modification.

Why not AGPLv3

The AGPL's network clause only triggers when modified code is run as a hosted service. This is a client with no server component, so the clause would never fire — and shipping it would falsely signal a server project to anyone reading the licence first.

# The position on content

The application is a general-purpose media player. It has no knowledge of what a user's playlist contains and exercises no editorial control over it.

Two rules follow, and both are enforced rather than merely stated:

  • The repository ships no playlist, no provider URL, no credentials, and no reference to where any of these may be obtained — including in tests, fixtures, issues and documentation. Test fixtures are synthetic; CI greps for provider URLs and for the forbidden brand string on every run.
  • The README states plainly that Quiblo supplies no content, and that users are responsible for the legality of the sources they configure. It must not link to, recommend, or describe how to obtain any playlist or provider.

Synthetic test data uses .invalid hostnames (RFC 2606), so nothing in the repository resolves even by accident.

# What we owe the code and services we use

Both apps list every third-party component they ship, under Settings — on the television it is at the bottom, under About, beside the version. Nearly all of them are Apache-2.0, which requires those notices to travel with the binary; one is MIT.

That list used to be kept by hand, and a list kept by hand stops being true without ever failing. It is now checked against the build: a task resolves what each app actually ships — several hundred modules, not the forty named in the version catalogue — and the build fails when something ships that the list does not mention. The first run found 118 components listed nowhere, including the cryptography library that holds your password.

Two services are credited rather than bundled, and each sentence sits beside the switch that turns its feature on:

  • The Movie Database. "This product uses the TMDB API but is not endorsed or certified by TMDB." It runs on a key you supply, and does nothing without one.
  • iptv-org, the community-maintained channel list that fills in logos your playlist did not provide. Off until you turn it on.

# Privacy, as an architectural rule

Two of our architectural invariants are privacy properties, and they are held to the same standard as any other correctness rule:

  • The app never phones home. No analytics, no crash-reporting SDK, no telemetry, no account and no server of ours. Outbound traffic goes to hosts the user explicitly configured, with one named exception: a request for the public release manifest on our GitHub releases page, once per launch, which sends nothing about the device or the viewer and can be switched off in Settings. The optional metadata and channel-logo features are the only third-party hosts, both are off by default, and both are the user's own choice to enable.
  • Credentials never leave the device. Xtream usernames and passwords are stored encrypted in DataStore — never in the database, so a database export or a debug dump cannot leak them — and are never written to logs, exports or crash traces. The backup file says so on screen: "Passwords are never written to the file — you will re-enter them after importing."

The permissions the app requests are INTERNET and ACCESS_NETWORK_STATE. Two more arrive transitively — WAKE_LOCK from Media3, which is what stops the screen sleeping mid-playback, and a self-scoped signature permission from androidx that is not user-visible. There is no storage permission: file export and import go through the system document picker, so the file lands wherever the user chooses and the app never asks for access to anything else.