NEMO is an Android network conditioner for testing apps under degraded mobile and Wi-Fi conditions.
It runs as a local VpnService, forwards traffic through a userspace datapath, and applies configurable network degradation without requiring root.
- preset network profiles
- one custom profile
- latency
- jitter
- uplink and downlink bandwidth limiting
- packet loss
- temporary traffic stalls
- per-app targeting
Clone with submodules:
git clone --recurse-submodules <repo-url>
cd <repo-directory>If you already cloned the repo:
git submodule update --init --recursiveBuild a debug APK:
./gradlew :app:buildDebugThe APK will be produced under:
app/build/outputs/apk/debug/
Create a signing keystore:
keytool -genkeypair -v \
-keystore nemo-release.keystore \
-alias nemo \
-keyalg RSA \
-keysize 2048 \
-validity 10000Create a local keystore.properties from the example:
cp keystore.properties.example keystore.propertiesThen set:
storeFilestorePasswordkeyAliaskeyPassword
Build a signed release APK:
./gradlew :app:assembleReleaseOr an Android App Bundle:
./gradlew :app:bundleRelease- Android app code lives in
app/src/main/java - native datapath and conditioner code lives in
app/src/main/jni zdtunis included as a git submodule insubmodules/zdtun- synthetic TCP loss is asymmetric by design: downlink TCP packets are not dropped directly; instead loss is modeled through uplink ACK loss to produce more realistic TCP degradation in the local VPN datapath
NEMO builds on ideas explored in:
- PCAPdroid by Emanuele Faranda
- Network Link Conditioner by Apple
It also depends on: