dumbtv
dumbtv takes the ads, screen tracking and update nags out of your Fire TV over ADB. No root, none of your apps touched, every step can be undone. Free and open source.
翻譯準備中
正在載入完整 README。 以下為已儲存的摘錄。
A simple, fully free-software WireGuard VPN client
for Android. It manages tunnel profiles and connects — nothing more.檢視完整 README ↗A simple, fully free-software WireGuard VPN client for Android. It manages tunnel profiles and connects — nothing more.
.conf file;
export a tunnel back to a standard wg-quick .conf (guarded by device
authentication — the file contains the private key).| Purpose | Component | License |
|---|---|---|
| WireGuard tunnel library + wg-quick parser | com.wireguard.android:tunnel | Apache-2.0 |
Userspace WireGuard (libwg-go.so) | wireguard-go | MIT |
wg / wg-quick binaries (libwg.so, libwg-quick.so) | wireguard-tools | GPL-2.0 |
| QR code scanning | com.journeyapps:zxing-android-embedded | Apache-2.0 |
| UI | AndroidX Jetpack Compose (Material 3) | Apache-2.0 |
KabelWacht is licensed AGPL-3.0-or-later. The dependencies keep their
own (compatible) licenses — see NOTICE. The wg/wg-quick binaries are
GPL-2.0 programs invoked as separate subprocesses (aggregation); AGPL-3.0 imposes no
copyleft on them and they impose none on the app.
Requirements: JDK 17, the Android SDK (compile/target SDK 36, min SDK 29), plus the NDK 27.2.12479018 and CMake 3.22.1 (WireGuard is built from source, see below). Clone with submodules:
git clone --recursive https://github.com/muelli/KabelWacht
# or, in an existing clone:
git submodule update --init --recursive
./gradlew assembleDebug # debug APK -> app/build/outputs/apk/debug/
./gradlew testDebugUnitTest # unit tests
./gradlew lint # Android lint
./gradlew assembleRelease # minified release APK (unsigned)
The wrapper pins Gradle; local.properties (with sdk.dir=...) is created
automatically by Android Studio, or write it by hand. It is git-ignored.
KabelWacht does not ship the prebuilt com.wireguard.android:tunnel AAR. The
:tunnel module compiles the WireGuard tunnel library —
including libwg-go.so (wireguard-go), libwg.so and libwg-quick.so
(wireguard-tools) — from the pinned third_party/wireguard-android
submodule via the NDK. Every binary in the APK is built here from source.
The release build is byte-for-byte reproducible: the same source produces an
identical APK regardless of build path or time (Go's -trimpath/-buildid=,
--build-id=none, and elf-cleaner remove the usual sources of non-determinism).
.github/workflows/reproducible.yml enforces
this on every tag by building twice from two independent checkouts and diffing the
results. Verify locally:
./gradlew clean assembleRelease && sha256sum app/build/outputs/apk/release/*-unsigned.apk
# clean and build again — the hash is identical
app/src/main/java/com/github/muelli/kabelwacht/
├── data/ ConfigStore (file-per-tunnel), TunnelRepository, TunnelSearch,
│ TunnelRunConditions + ConditionsStore (automation rules)
├── vpn/ TunnelManager (wraps GoBackend), WgTunnel
│ └── automation/ NetworkStateMonitor, AutomationEngine, monitor service
├── ui/ Compose screens: list/, edit/, conditions/, nav/, theme/
├── KabelWachtApp.kt Application + manual DI container
└── MainActivity.kt
Profiles are stored as individual wg-quick .conf files in the app's private
storage; the tunnel name is the file name and the network interface name (so it must
be 1–15 chars of A–Z a–z 0–9 _ = + . -).
The version is driven entirely by Git history to ensure strict monotonic versioning for F-Droid without manual bumps. The versionCode is the total number of commits (git rev-list --count HEAD).
Every push to the main branch automatically builds and publishes an -rc (release candidate) version to the custom F-Droid repository.
To cut a stable release:
Find the current commit count to use as the version number (N):
N=$(git rev-list --count HEAD)
echo $N
Add release notes at fastlane/metadata/android/en-US/changelogs/N.txt.
Tag the commit with vN (e.g. v78) and push:
git tag vN && git push origin vN
Pushing the vN tag triggers release.yml and publish-fdroid.yml, which:
versionName drops the -rc suffix),changelogs/N.txt (falling back to auto-generated notes if it's missing),Signing is optional via the APP_SIGNING_SEED secret (see Signing).
Without it the release APK is published unsigned (F-Droid rebuilds and signs from
source anyway).
.github/workflows/ci.yml — on push/PR: lint, unit
tests, and assembleDebug; uploads the debug APK and reports as artifacts..github/workflows/release.yml — the release flow
described above.scripts/ci-local.sh # act (Docker) if available, else Gradle directly
scripts/ci-local.sh --gradle # force the fast, no-Docker Gradle path
scripts/ci-local.sh --act # force full GitHub Actions emulation via act
The script runs the same tasks as the CI build job (lint testDebugUnitTest assembleDebug). Full emulation uses act with the
settings in .actrc; install it with e.g. brew install act (needs
Docker).
The phone screenshots in the F-Droid listing are produced by
scripts/screenshots.sh: it builds the app, boots a
headless emulator (creating the shots AVD on first run), stages a demo tunnel,
and captures the list, editor, and add-menu into
fastlane/metadata/android/en-US/images/phoneScreenshots/. Needs the Android
emulator + the android-35 x86_64 system image and a JDK 17.
The store listing (descriptions, icon, screenshots, changelogs) comes from the
fastlane metadata in this repository;
fdroid/com.github.muelli.kabelwacht.yml
is the app's build/listing metadata, consumed by the publishing workflow below.
You can also run your own F-Droid repository, hosted on GitHub Pages and updated
automatically on every push to main and every tag by
.github/workflows/publish-fdroid.yml.
-rc builds (release candidates). The F-Droid client will not auto-update users to these builds (they are hidden via CurrentVersionCode), so it's safe to push continuously.To prevent repository size bloat, the workflow statelessly retains only the latest 5 stable builds and 2 -rc builds, rewriting the fdroid-repo branch from scratch on every run. Note: You must disable branch protection (allow force pushes) on the fdroid-repo branch for this to work.
Two signing identities exist — the app key (the APK's identity for updates) and
the repo index key (its fingerprint is the repository's identity) — and each is
driven entirely by one high-entropy seed string stored as a GitHub Actions
secret. scripts/derive-signing-key.py
deterministically derives the EC P-256 private key, keystore, alias, and passphrase
from the seed; the public certificates are pinned in signing/. The
derivation is a versioned contract: the seed is the key — back it up like one,
and never change the derivation for existing seeds.
One-time setup:
Generate two seeds (e.g. openssl rand -base64 48), save each in your password
manager — the seed is the key; losing it means losing the identity — then:
gh secret set APP_SIGNING_SEED # paste the first seed at the hidden prompt
gh secret set FDROID_SIGNING_SEED # paste the second
Run the Bootstrap signing certificates workflow once (Actions →
Bootstrap signing certificates → Run). It derives both identities, and opens a
PR adding the public certificates under signing/ — merge it. The run summary
shows the certificate fingerprints.
Confirm repo_url in fdroid/config.yml matches your Pages
URL (https://<owner>.github.io/<repo>/fdroid/repo). Serving under /fdroid/repo
lets plain https:// links open F-Droid directly.
Push a vN tag. The first run creates the fdroid-repo branch and tries to enable
Pages automatically; if it can't, set Settings → Pages → Source: branch
fdroid-repo / (root) once.
After that, publishing is fully automatic. Users add your repo once — the workflow
writes a landing page at https://<owner>.github.io/<repo>/ with the URL,
fingerprint, and a tap-to-add link. If the seeds are absent the workflow logs a
notice and skips, so it never breaks a tag push.
One active tunnel at a time. Per-app split tunnelling is intentionally out of scope for now.
WireGuard is a registered trademark of Jason A. Donenfeld. This project is not officially affiliated with or endorsed by the WireGuard project.