Add the Android app - #1
Merged
Merged
Conversation
A native Kotlin/Jetpack Compose client for ezvpn. The app, EzvpnVpnService, TunnelsManager, the AndroidKeyStore-encrypted secret and profile stores, the shared auth-key manager, and EzvpnNative (the JNI binding to libezvpn.so, whose symbols fix the class at dev.flexaccess.ezvpn.EzvpnNative) live in :app; the pure-Kotlin :tunnelcore module holds the CIDR math (including the bypass-by-subtraction route plan, since VpnService has no excludeRoute before API 33), the profile model and editor validation, the VpnService.Builder plan, and the split-DNS rules, all unit-tested on the JVM. Split DNS (match domains) is implemented by pointing the VPN's DNS at the core's in-tunnel forwarder address, routed as a host route, with the underlying network's resolvers and protect()ed fallback sockets handed to the core at connect time. Network changes disconnect; split-tunnel prefixes that overlap the current Wi-Fi/Ethernet subnet are refused; always-on starts connect the last-used profile. libezvpn.so comes from the pinned ezvpn release zip (tag + sha256 in gradle.properties, scripts/bump-jnilibs.sh) or, with EZVPN_LOCAL_JNILIBS=1, from the sibling ../ezvpn/dist/android build; scripts/run-device.sh builds, installs, launches, and tails logcat on the connected device. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WZxQCX8Kwr4yZV6R96TaYP
CI fails without a valid ezvpn release pin instead of building an APK with no native library; README lists the app unit tests; the jniLibs download has timeouts. Stores: AuthKeyStore no longer persists the pruned list at load, rename of an unknown id is an error, and the mutators are synchronized; AuthKey guards the JNI call; ProfileStore keeps a load-error state that refuses writes and commits lastProfileId synchronously; TunnelsManager clears the pending id from live state and lets a queued connect start when no service exists; the service resolves ConnectivityManager once and checks it. UI: consent pending id survives recreation; ConnPathSheet has loading and error states; EzvpnRoot pops a missing profile from an effect; clipboard null-checks the service; the relay token stays out of saved state and is loaded off-main; key operations run on a background dispatcher; the list screen uses string resources; the launcher foreground fits the adaptive safe zone and the duplicate round icon is gone. tunnelcore: IPv4 literals are built directly with octet range checks, NetworkConfig.parse rejects malformed mtu/prefix_len6, routes are stored in canonical form; tests cover the malformed fields. Scripts: portable sha256/sed in bump-jnilibs.sh, emulator refusal in run-device.sh. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WZxQCX8Kwr4yZV6R96TaYP
Fills in the sha256 of the published libezvpn-android.zip so the default (non-local) build and the CI pin check work; bumps versionCode. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WZxQCX8Kwr4yZV6R96TaYP
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
EzvpnVpnServicerunning the Rust core (libezvpn.so) inside aVpnService,TunnelsManager, encrypted profile/auth-key stores, and theEzvpnNativeJNI binding.tunnelcoremodule (CIDR math, route subtraction for the underlay bypass, profile validation,TunnelPlan, split-DNS rules) with JVM unit tests.libezvpn-android.zipfrom the ezvpn release (v0.0.41, sha256 ingradle.properties);EZVPN_LOCAL_JNILIBS=1builds against the sibling checkout.Test plan
./gradlew :tunnelcore:test :app:testDebugUnitTest :app:assembleDebug(clean pinned download path)🤖 Generated with Claude Code
https://claude.ai/code/session_01WZxQCX8Kwr4yZV6R96TaYP