The phone client manages VD server deployment, car auto-update, and 3-connection relay. The phone app:
targetFpsUPDATING_CAR and auto-updates car app via dadb if version mismatch/sdcard/DiLinkAuto/ and starts VD server (with FPS arg)Dispatchers.IONo screen capture. No MediaProjection. All video comes from the VD server process.
Application class. Creates notification channels (dilinkauto_service, dilinkauto_update), initializes UpdateManager and ShizukuManager on create.
Self-update mechanism that checks GitHub Releases for new versions.
checkForUpdate(force): Queries https://api.github.com/repos/andersonlucasg3/dilink-auto-android/releases/latest, compares semver from tag name against installed versionName. Respects 6-hour cooldown unless forced.downloadUpdate(): Downloads APK via HttpsURLConnection with progress reporting. Verifies via PackageManager.getPackageArchiveInfo().installUpdate(context): Uses Shizuku pm install -r for silent installation when Shizuku is available; falls back to system package installer via FileProvider URI otherwise.StateFlow.Entry point with two screens:
Foreground service that manages the phone-car connection lifecycle with 3 dedicated connections. Auto-starts when the phone app is opened (e.g., via car USB ADB).
0.0.0.0, handles handshake, heartbeat, app commands, DATA channelDispatchers.IO to avoid NetworkOnMainThreadException on localhost touch writesdeployAssets(): extracts vd-server.jar to sdcard, app-server.apk to filesDirUPDATING_CAR → auto-updates car app via dadb (WiFi ADB, dadb 1.2.10)TRANSPORT_WIFI filtered — only reacts to WiFi changes, ignores 3G/4G mobile data fluctuationsFileLog.rotate() on service start — archives previous session logAccepts reverse connection from the VD server process on localhost:19637. Takes two Connection params: videoConnection and controlConnection.
MSG_VIDEO_CONFIG, MSG_VIDEO_FRAME, MSG_STACK_EMPTY, MSG_DISPLAY_READYCMD_LAUNCH_APP, CMD_GO_BACK, CMD_GO_HOME, CMD_INPUT_TOUCH (0x32)videoConnection.sendVideo() (isolated from control traffic)MSG_STACK_EMPTY) forwarded to car via controlConnection.sendControl()FrameCodec.writeAll() under writeLockcmd display power-on 0 + KEYCODE_WAKEUP) as safety net when VD server process is killed before cleanupFallback shell command helper. Provides execShell() and execFast() using Runtime.exec() for VD server operations and display power management when direct API reflection fails.
Manages app launching on the physical display when VD is not in use. Bridges to InputInjectionService for gesture-based input injection.
MediaProjection + MediaCodec H.264 encoder using AUTO_MIRROR virtual display. Alternative encoding path (not used in the primary streaming pipeline which flows through VD server).
File-based logger that bypasses Android logcat filtering (HyperOS filters Log.i/d for non-system apps).
/sdcard/DiLinkAuto/client.logrotate(): archives current log as client-YYYYMMDD-HHmmss.log, starts freshzipLogs(): creates dilinkauto-logs.zip from all .log files for sharingandroid.util.Log.* for standard logcat outputTouch events arrive from the car via the input connection as CMD_INPUT_TOUCH (0x32) with raw MotionEvent data. The handleInputFrame is dispatched on Dispatchers.IO (not Main) to allow localhost socket writes. The phone streams DOWN/MOVE/UP events with pointerId directly to the VD server, which handles full MotionEvent construction with all active pointers.
| Permission | Purpose |
|---|---|
| MANAGE_EXTERNAL_STORAGE | All Files Access for sdcard deployment of VD JAR |
| Accessibility Service | Touch injection on virtual display via dispatchGesture (no event monitoring) |
| Notification Access | Forward notifications to car (with progress) |
| Shizuku API | Elevated shell access for ADB-free VD server deployment and silent self-update |
| QUERY_ALL_PACKAGES | App launcher grid |
| REQUEST_INSTALL_PACKAGES | Car app auto-update via dadb |