[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-735":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":13,"openIssues":14,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":16,"stars7d":17,"stars30d":18,"stars90d":15,"forks30d":15,"starsTrendScore":19,"compositeScore":20,"rankGlobal":9,"rankLanguage":9,"license":21,"archived":22,"fork":22,"defaultBranch":23,"hasWiki":24,"hasPages":22,"topics":25,"createdAt":9,"pushedAt":9,"updatedAt":26,"readmeContent":27,"aiSummary":28,"trendingCount":15,"starSnapshotCount":15,"syncStatus":29,"lastSyncTime":30,"discoverSource":31},735,"anubis","sogonov\u002Fanubis","sogonov","Android app manager with VPN integration. Manages groups of apps by freezing\u002Funfreezing them based on VPN connection state.",null,"Kotlin",1193,33,16,57,0,6,14,52,18,17.59,"MIT License",false,"main",true,[],"2026-06-12 02:00:17","# Anubis\n\nAndroid app manager with VPN integration. Manages groups of apps by freezing\u002Funfreezing them based on VPN connection state.\n\nUnlike sandbox-based solutions (Island, Insular, Shelter), which only isolate apps in a work profile where they **can still detect VPN** through the shared network stack, Anubis uses `pm disable-user` to **completely disable** apps at the system level. A disabled app cannot run any code, detect any network interfaces, or send any data.\n\n## Features\n\n- **App groups** with different network policies:\n  - **Local** — apps frozen when VPN is active, launched without VPN\n  - **VPN Only** — apps frozen when VPN is inactive, launched through VPN\n  - **Launch with VPN** — never frozen, but launching triggers VPN activation\n- **Home screen launcher** — tap app icons to launch with correct VPN state\n  - Grayscale icons for frozen\u002Fdisabled apps\n  - Long press for freeze\u002Funfreeze, shortcut creation, group management\n- **VPN client orchestration** — auto start\u002Fstop for supported clients, any client works in manual mode\n- **Custom VPN client** — select any installed app as VPN client from the app list\n- **Active VPN client detection** — identifies which app owns the VPN via `dumpsys connectivity` owner UID\n- **Pinned shortcuts** — home screen shortcuts that orchestrate freeze\u002FVPN\u002Flaunch in one tap\n- **Network check** — ping, country, city (IP hidden by default for privacy)\n- **Quick Settings tile** — toggle from notification shade\n- **Auto-freeze on boot** and on app launch if VPN is already active\n- **Background VPN monitoring** — auto-freeze when VPN is toggled outside Anubis (opt-in in Settings)\n- **VPN disconnect** — multi-step: API → dummy VPN takeover → force-stop → kill\n\n## How It Works\n\n### Freeze Mechanism\nUses Shizuku to execute `pm disable-user --user 0 \u003Cpackage>` which completely disables an app at the OS level. The app cannot:\n- Run any background services\n- Receive broadcasts\n- Access network interfaces\n- Detect VPN or proxy\n\nThis is fundamentally different from sandboxing, which still allows the app to run and inspect the network stack.\n\n### VPN Start\nFor clients with a known API, Anubis sends shell commands via Shizuku. Three control modes:\n- **SEPARATE** — independent start and stop commands. Examples: NekoBox (`QuickEnableShortcut` \u002F `QuickDisableShortcut` activities), Incy (`CONNECT` \u002F `DISCONNECT` broadcasts), Clash Meta (`START_CLASH` \u002F `STOP_CLASH` activity).\n- **TOGGLE** — single command that toggles on\u002Foff. Examples: v2rayNG \u002F Happ \u002F v2rayTun \u002F V2Box \u002F olcng (widget broadcast), Exclave \u002F husi (`QuickToggleShortcut` activity).\n- **MANUAL** — no external start\u002Fstop API. Anubis opens the app and the user taps connect.\n\n### VPN Stop\nToggle commands are unreliable for stopping (can re-enable immediately), so Anubis uses a multi-step approach:\n1. **API stop** — only for SEPARATE clients with explicit stop command\n2. **Dummy VPN** — establish our own VPN to revoke theirs, then close ours\n3. **`am force-stop`** — kill the detected VPN app process\n\nApps are never unfrozen while VPN is still active.\n\n### VPN Detection\nExtracts the VPN network owner UID from `dumpsys connectivity` by matching `type: VPN[` pattern, then resolves UID → package name via `pm list packages --uid`. Works with any VPN client, including unknown\u002Fcustom ones.\n\n## Supported VPN Clients\n\nVariants of the same brand (e.g. v2rayNG Play and F-Droid) are grouped together in the Settings picker.\n\n### Full control (independent start\u002Fstop)\n\n| Client | Package(s) | Method |\n|--------|------------|--------|\n| NekoBox | `moe.nb4a` | `QuickEnableShortcut` \u002F `QuickDisableShortcut` activities |\n| Incy | `llc.itdev.incy` | `CONNECT` \u002F `DISCONNECT` broadcasts |\n| Clash Meta | `com.github.metacubex.clash.meta` (Meta), `com.github.metacubex.clash.alpha` (Alpha) | `START_CLASH` \u002F `STOP_CLASH` on `ExternalControlActivity` |\n| FlClash | `com.follow.clash` | `action.START` \u002F `action.STOP` on `TempActivity` |\n| FlClashX | `com.follow.clashx` | `action.START` \u002F `action.STOP` on `TempActivity` |\n\n### Auto-toggle (start via widget\u002Fshortcut, stop via dummy-VPN fallback)\n\n| Client | Package(s) | Method |\n|--------|------------|--------|\n| v2rayNG | `com.v2ray.ang` (Play), `com.v2ray.ang.fdroid` (F-Droid) | Widget broadcast |\n| Happ | `com.happproxy` (Play), `su.happ.proxyutility` (Github) | Widget broadcast |\n| v2rayTun | `com.v2raytun.android` | Widget broadcast |\n| V2Box | `dev.hexasoftware.v2box` | Widget broadcast |\n| olcng | `xyz.zarazaex.olc`, `xyz.zarazaex.olc.fdroid` | Widget broadcast |\n| Exclave | `com.github.dyhkwong.sagernet` | `QuickToggleShortcut` activity |\n| husi | `fr.husi` | `QuickToggleShortcut` activity |\n| [Tunguska](https:\u002F\u002Fgithub.com\u002FAcionyx\u002Ftunguska) | `io.acionyx.tunguska` | Full (start\u002Fstop) | Token-gated exported activity |\n\n### Manual (Anubis opens the app, user connects)\n\n| Client | Package | Why manual |\n|--------|---------|------------|\n| AmneziaVPN | `org.amnezia.vpn` | No exported start\u002Fstop API (Qt app) |\n| AmneziaWG | `org.amnezia.awg` | `SET_TUNNEL_UP`\u002F`DOWN` requires a tunnel-name extra — planned for a later release |\n| WireGuard | `com.wireguard.android` | Same mechanism as AmneziaWG |\n| WG Tunnel | `com.zaneschepke.wireguardautotunnel` | `RemoteControlReceiver` is gated by a user-defined secret key |\n| TeapodStream | `com.teapodstream.teapodstream` | Only `MainActivity` exported |\n| Karing | `com.nebula.karing` | Only `MainActivity` + QS tile exported |\n| **Any app** | — | Select in Settings → \"Other client\" |\n\n### Tunguska\n\nTunguska integrates differently from widget-toggle clients. Instead of a single broadcast toggle, it exposes explicit `AUTOMATION_START` and `AUTOMATION_STOP` actions through a dedicated exported activity, guarded by a per-client automation token. Anubis stores that token in encrypted preferences and uses it for separate start and stop orchestration.\n\nQuick setup:\n\n1. Install [Tunguska](https:\u002F\u002Fgithub.com\u002FAcionyx\u002Ftunguska) and import a working profile.\n2. Start Tunguska once manually and grant Android VPN permission.\n3. In Tunguska, open `Anubis Integration`, enable automation, and copy the generated token.\n4. In Anubis, select `Tunguska` as the VPN client and paste the token into the VPN client settings.\n5. Use Anubis normally: it can unfreeze Tunguska, send explicit start\u002Fstop commands, and freeze it again while idle.\n\n### Discovering VPN Client APIs\n\nFor closed-source clients, broadcast actions can be discovered via APK analysis using [jadx](https:\u002F\u002Fgithub.com\u002Fskylot\u002Fjadx):\n\n1. **Resources** → find `app_widget_name` in `strings.xml` (resources are not obfuscated)\n2. **Manifest** → find `\u003Creceiver>` with `android.appwidget.provider` metadata → get class name\n3. **Receiver code** → find `setAction(\"...\")` → this is the broadcast action\n4. **Verify** → check `onReceive()` for the `isRunning ? stop : start` toggle pattern\n\nTwo common patterns discovered so far:\n\n**v2ray\u002Fxray forks** (v2rayNG, Happ, V2Box, v2rayTun, olcng) — widget broadcast:\n```\nAction:   \u003Cpackage>.action.widget.click\nReceiver: \u003Cpackage>.receiver.WidgetProvider\n```\n```shell\nam broadcast -a \u003Cpackage>.action.widget.click -n \u003Cpackage>\u002F.receiver.WidgetProvider\n```\n\n**SagerNet forks** (NekoBox, Exclave, husi) — exported shortcut activities:\n```\nActivity: QuickEnableShortcut \u002F QuickDisableShortcut (separate)\n     or:  QuickToggleShortcut (single toggle)\n```\n```shell\nam start -n \u003Cpackage>\u002F\u003Cactivity-fully-qualified-name>\n```\n\nThis is standard Android IPC discovery, not reverse engineering of protected code. Broadcast actions and exported activities are public interfaces by design.\n\n## Requirements\n\n- Android 10+ (API 29)\n- [Shizuku](https:\u002F\u002Fshizuku.rikka.app\u002F) installed and running\n- At least one VPN client installed\n\n## Setup\n\n1. Install and start Shizuku (via ADB or Wireless Debugging)\n2. Install Anubis\n3. Grant Shizuku permission when prompted\n4. Grant VPN permission when prompted (needed for dummy VPN disconnect)\n5. Go to **Apps** tab, assign apps to groups\n6. Select your VPN client in **Settings** (known or custom)\n7. Toggle stealth mode on the **Home** screen\n\n## Building\n\n```bash\n.\u002Fgradlew assembleDebug\n.\u002Fgradlew assembleRelease  # requires signing config\n```\n\nCreate `signing.properties` in project root:\n```properties\nstoreFile=release.keystore\nstorePassword=your_password\nkeyAlias=your_alias\nkeyPassword=your_password\n```\n\n## Tech Stack\n\n- Kotlin + Jetpack Compose (Material 3)\n- Shizuku API 13.1.5 (AIDL UserService pattern)\n- Room database with TypeConverters (app groups)\n- ConnectivityManager NetworkCallback (VPN state monitoring)\n- ShortcutManager (pinned shortcuts)\n\n## Roadmap\n\n- [ ] Per-client tunnel-name \u002F secret-key config so WireGuard, AmneziaWG and WG Tunnel can move from MANUAL to full control\n- [ ] Fourth app group with auto-unfreeze when VPN is turned off (banking \u002F messenger notifications)\n- [ ] Self-hosted `app_process` daemon to remove Shizuku dependency\n- [ ] Export\u002Fimport app group configuration\n- [ ] More VPN clients — PRs welcome, see \"Discovering VPN Client APIs\" above\n\n## License\n\nMIT\n","Anubis 是一款集成了VPN功能的Android应用管理器，能够根据VPN连接状态冻结或解冻应用程序组。其核心功能包括基于不同网络策略的应用分组管理、通过系统级命令完全禁用应用以防止其检测到任何网络接口或发送数据、以及自动化的VPN客户端控制等。特别适用于需要高度隐私保护和安全隔离的应用场景，如企业移动设备管理和个人隐私保护。使用Kotlin编写，并采用MIT许可证发布，确保了项目的开放性和可扩展性。",2,"2026-06-11 02:38:59","CREATED_QUERY"]