β οΈ This app draws an overlay and uses an accessibility service on a vehicle head unit; do not use it while driving. Read DISCLAIMER.md before installing. It has no access to the vehicle itself. MG and MG4 are third-party marks used only to identify compatibility; this independent project is not affiliated with or approved by SAIC Motor or MG Motor.
Swipe up from the bottom edge of the screen to quickly launch a user-selected app. Handy for fast, easy access to one specific app of your choice.
π‘ It pairs perfectly with EVLauncher, which is now the default swipe target. As the home launcher it stays warm in memory, so the swipe re-opens it almost instantly, for a clean, system-integrated home experience.
EVSwipe is independent: it needs no other EVSuite app, and it does not read or write the vehicle. It shares the suite's dark Material 3 theme, its CI/CD and security gates, and its two-channel release model.
EVSwipe is one app of EVSuite, a family of independent, offline-first apps for the MG4 head unit (Android Automotive OS 9). Each app installs on its own β pick only what you need. User guides and install instructions: https://malys.github.io/EVSuite/.
Discover the rest of the suite:
- Part of EVSuite
- Upgrading from v1.2 (or earlier) β please read
- Features
- Configuration
- Building
- Project documents
- Security
- Contributing
- Legal
The app is now signed with the EVSuite platform key, and its application id
changed from com.tommasov.evswipenovalauncher to com.evsuite.swipe. Either change
alone forces a fresh install: uninstall the previous version first, then install the new
one. Settings are stored per-app, so they are reset. The note below covers the earlier v1.4
key change and still applies to anyone coming from v1.2 or earlier.
Starting from v1.4 the app is signed with a new, stable signing key. Android does not allow installing an update over an app signed with a different key, so you cannot update on top of an older build: you must uninstall the previous version first, then install v1.4. This is a one-time step needed only to migrate to the new signed builds β every future update will install normally, with no uninstall. (Your settings are stored per-app, so they are reset on reinstall.)
- Swipe up from the bottom edge: Quickly launch your chosen app with a simple swipe-up gesture.
- Default target β EVLauncher: out of the box the swipe opens EVLauncher (
com.evsuite.launcher). Being the home launcher it stays warm, so it re-opens almost instantly. - Any app works too: Nova Launcher (or any installed app) can be chosen instead of the default from the EVSwipe main screen.
- Configuration: Select the app you want to launch by opening the EVSwipe app.
These options are configurable from the EVSwipe main screen:
- Two swipe areas: the bottom edge is split into a left and a right area. By default the left area triggers the back action (simulated physical back button) and the right area opens the selected app.
- Swap the swipe areas (left β right): exchanges the back and open actions between the two areas. The on-screen help labels at the bottom follow this setting β both their text and their background colour swap accordingly, so they always match the active layout.
- Hide the floating back button: hides the draggable floating back button, useful for car servicing (hidden by default).
- Show a loader while opening: shows a lightweight "Openingβ¦" overlay over the launch transition. It gives immediate feedback that the swipe was registered and masks the brief window flash while the target app is brought to the foreground (off by default).
- App version: the installed version name is shown in the top corner of the main screen.
- Check for updates: suspended during the suite safety and legal audit.
Standard Android project (Java + Kotlin, AGP 8.6, Gradle 8.7, minSdk 28 /
targetSdk 34). JDK 17 is required and pinned in mise.toml.
mise run build # stable debug APK
mise run build-unstable # unstable debug APK (OTA trigger audit-suspended)
mise run test # JVM unit tests, both channels
mise run permissions # permission-drift gate, same check the CI runs
Or directly:
./gradlew assembleStableDebug
./gradlew assembleUnstableDebug
APKs land under app/build/outputs/apk/<channel>/debug/.
To sign locally, in gradle.properties (never committed) or as environment
variables β the same EVSuite platform key used by EVProfile and EVTasker:
evsuite.keystore=/path/to/platform.keystore
evsuite.keystore.password=β¦
evsuite.key.alias=platform
evsuite.key.password=β¦
Two build flavors, like the sibling apps:
- stable β tagged releases, no self-update. The updater class is not in the
APK and the manifest declares no
INTERNETpermission, so the app is fully offline by construction. Installed from a USB stick. - unstable β a pre-release published on every push to
master; OTA is audit-suspended, so updates are manual. Application idcom.evsuite.swipe.unstable, so it installs beside a stable build.
If re-enabled after review, the unstable updater downloads to private cache, validates https and the GitHub allowlist
at every redirect, verifies the running app's certificate, then installs automatically via
pm. The cached APK is always deleted. Stable contains neither updater code nor network
permission.
mise run emulator-setup # one-off: SDK images + both AVDs (needs /dev/kvm)
mise run emulator-screen # API 28 at MG4 panel geometry β the useful one for UI work
mise run emulator-car # API 33 Automotive β automotive system UI, wrong OS version
mise run run # build, install and start on whatever device is connected
mise run emulator-stop
Neither profile is faithful on both axes: the vehicle runs AAOS 9 (API 28), but Google
publishes no Automotive system image below API 33. The screen profile is the one that
matters here β the project targets 1920x1080 @ 160dpi
(SWI68-29958-1300R69). The 1920Γ720 figure is the usable app area left under the
system UI; set EMU_HEIGHT=720 in mise.toml and re-run emulator-setup to model that
instead.
The AVDs are named per repo (mg4simple-*, evswipe-*), matching the evtasker-* /
evabrp-* convention used by the sibling projects.
The overlay and accessibility permissions this app is built around are both "special":
adb install -g does not grant them, and without them the app only shows its permission
gate. mise run run calls mise run grant-permissions, which sets the overlay appop and
appends the service to enabled_accessibility_services. That is a development shortcut for
a throwaway emulator β on a real head unit you grant both through the system screens,
deliberately.
| Workflow | Trigger | Blocking |
|---|---|---|
tests.yml |
push / PR | JVM unit tests, both channels |
security.yml |
push / PR | permission-drift gate + gitleaks; mobsfscan / semgrep / OWASP are informational SARIF |
unstable.yml |
push to master |
builds and publishes the rolling unstable pre-release |
release.yml |
v* tag |
builds, checks, and publishes the stable APK |
Every uses-permission must be listed with a justification in
.github/security/permission-allowlist.txt, or the build fails.
| Document | What it covers |
|---|---|
| SECURITY.md | Threat model, the accessibility/overlay posture, how to report a vulnerability privately |
| DISCLAIMER.md | No warranty, no liability, and what running this on a vehicle head unit means concretely |
| CONTRIBUTING.md | Ground rules and the checks to run before a PR |
| DESIGN.md | The EVSuite design system |
| CHANGELOG.md | Release history |
| LICENSE.md | MIT, and where the forked code comes from |
| AGENTS.md | Architecture notes for contributors and coding agents |
This app holds an accessibility service and draws over other apps, so its
declarations are kept as narrow as the code: typeWindowStateChanged only, with
canRetrieveWindowContent="false". AccService forwards the foreground package
name to SwipeService and performs the global back action β it never reads window
content. See SECURITY.md for the full posture and what is in scope
for a report.
Read CONTRIBUTING.md before opening a pull request. In short: this code runs in a moving vehicle, so changes stay small, carry tests, and say in the diff what would break without them. Anything touching the interface follows DESIGN.md.
Released under the MIT License. EVSwipe is a fork of Tommasov/EV_Swipe_Launcher, which publishes no licence of its own; see LICENSE and LICENSE.md. Provided as is, without warranty or liability β see DISCLAIMER.md.