Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,11 @@ jobs:
scripts/clean-device.sh scripts/update-json.sh \
kmod/test/run.sh kmod/test/build-kernel.sh kmod/test/init.sh \
kmod/test/run-kpm.sh kmod/test/init-kpm.sh kmod/test/build-source-kernel.sh
# The app's root probes. They are assembled from these files plus a
# variable prelude, so they are checked as POSIX sh (the device shell
# is mksh) and on their own — a stray apostrophe in one of them once
# killed the whole batched command silently for a release.
shellcheck -s sh lsposed/app/src/main/resources/shell/*.sh

# C (kernel module)
- name: clang-format
Expand Down
21 changes: 21 additions & 0 deletions lsposed/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,27 @@ duplication / god-function drift that AI-assisted edits cause when each change
only sees its local neighbourhood. **Reuse the abstractions below — don't
reinvent them.** `grep` for an existing helper before writing a new one.

## Where things live

The app package is no longer one flat directory. `hook/` is the load-bearing
split (next section); the rest group a feature's screen, its cache and its pure
model together:

| package | holds |
|---|---|
| `hook/` | everything LSPosed loads into `system_server` |
| `picker/` | the Hiding tab: app list, target model, per-app caches |
| `diagnostics/` | the check suite, the canonical report, the Diagnostics screen |
| `settings/` | Settings and its sub-screens, plus the UI preference store |
| `debug/` | the bundle, the logcat recorder, kernel-image export |
| `statistics/`, `startup/` | the Statistics tab; MainActivity and startup wiring |
| `ui/`, `checks/`, `generated/` | design system, the JNI probe binding, codegen |

What stays in the root package is the shared vocabulary both sides use —
`StorageConfig`, `ShellUtils`, `RootSnapshotCache`, `HookRegistry`,
`DashboardData`, the agent bridge. Moving those buys import churn and nothing
else; they belong to no single feature.

## Two processes, one APK

The single most important thing about this module: `hook/` is loaded by LSPosed
Expand Down
2 changes: 1 addition & 1 deletion lsposed/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
tools:ignore="GoogleAppIndexingWarning">

<activity
android:name=".MainActivity"
android:name=".startup.MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package dev.okhsunrog.vpnhide

import dev.okhsunrog.vpnhide.diagnostics.LayerStatus
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject
Expand Down
34 changes: 34 additions & 0 deletions lsposed/app/src/main/kotlin/dev/okhsunrog/vpnhide/AgentControl.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,41 @@ package dev.okhsunrog.vpnhide

import android.content.Context
import android.net.ConnectivityManager
import dev.okhsunrog.vpnhide.debug.LogcatRecorder
import dev.okhsunrog.vpnhide.debug.StateContentOptions
import dev.okhsunrog.vpnhide.debug.VpnHideState
import dev.okhsunrog.vpnhide.debug.buildLsposedConfigText
import dev.okhsunrog.vpnhide.debug.buildVpnHideState
import dev.okhsunrog.vpnhide.debug.captureBootLsposedLogcat
import dev.okhsunrog.vpnhide.debug.exportDebug
import dev.okhsunrog.vpnhide.debug.isoNow
import dev.okhsunrog.vpnhide.debug.setDebugLoggingEnabled
import dev.okhsunrog.vpnhide.diagnostics.AppProbeStats
import dev.okhsunrog.vpnhide.diagnostics.CaptureDiff
import dev.okhsunrog.vpnhide.diagnostics.DetectionMethod
import dev.okhsunrog.vpnhide.diagnostics.DiagnosticGate
import dev.okhsunrog.vpnhide.diagnostics.DiagnosticsCache
import dev.okhsunrog.vpnhide.diagnostics.MethodSurface
import dev.okhsunrog.vpnhide.diagnostics.buildAppProbeStats
import dev.okhsunrog.vpnhide.diagnostics.buildHookDiagnosticsText
import dev.okhsunrog.vpnhide.diagnostics.diffCapture
import dev.okhsunrog.vpnhide.diagnostics.snapshotCounters
import dev.okhsunrog.vpnhide.generated.HookIds
import dev.okhsunrog.vpnhide.picker.AppListCache
import dev.okhsunrog.vpnhide.picker.AppSummary
import dev.okhsunrog.vpnhide.picker.TargetsSnapshot
import dev.okhsunrog.vpnhide.picker.applyAutoHiddenPackages
import dev.okhsunrog.vpnhide.picker.labelWithUsers
import dev.okhsunrog.vpnhide.picker.parseTargetsSnapshot
import dev.okhsunrog.vpnhide.picker.resolveHookSelection
import dev.okhsunrog.vpnhide.picker.resolveNativeHookSelection
import dev.okhsunrog.vpnhide.picker.toAutoHideSignal
import dev.okhsunrog.vpnhide.picker.updateManualHiddenPackages
import dev.okhsunrog.vpnhide.settings.removeConfiguredPackages
import dev.okhsunrog.vpnhide.statistics.BackendStatistics
import dev.okhsunrog.vpnhide.statistics.StatisticsRow
import dev.okhsunrog.vpnhide.statistics.StatisticsState
import dev.okhsunrog.vpnhide.statistics.buildStatisticsState
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.File
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package dev.okhsunrog.vpnhide

import android.content.Context
import android.util.Log
import dev.okhsunrog.vpnhide.diagnostics.token
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package dev.okhsunrog.vpnhide

import android.content.Context
import dev.okhsunrog.vpnhide.debug.StateContentOptions
import dev.okhsunrog.vpnhide.debug.VpnHideState
import dev.okhsunrog.vpnhide.diagnostics.verdict
import dev.okhsunrog.vpnhide.settings.removeConfiguredPackages
import kotlinx.serialization.Serializable
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package dev.okhsunrog.vpnhide

import dev.okhsunrog.vpnhide.diagnostics.RoutingGateCache
import dev.okhsunrog.vpnhide.picker.TargetsCache
import dev.okhsunrog.vpnhide.statistics.StatisticsCache
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package dev.okhsunrog.vpnhide

import android.content.Context
import dev.okhsunrog.vpnhide.picker.AppAutoHideSignal
import dev.okhsunrog.vpnhide.picker.applyAutoHiddenPackages
import dev.okhsunrog.vpnhide.picker.autoHiddenPackagesNeedReconcile

/**
* Launches the native activators. The app does not fan out wire snapshots
Expand Down
16 changes: 16 additions & 0 deletions lsposed/app/src/main/kotlin/dev/okhsunrog/vpnhide/DashboardData.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,24 @@ import android.content.pm.PackageManager
import android.database.sqlite.SQLiteDatabase
import android.os.Build
import android.os.SystemClock
import dev.okhsunrog.vpnhide.diagnostics.DiagnosticGate
import dev.okhsunrog.vpnhide.diagnostics.DiagnosticReport
import dev.okhsunrog.vpnhide.diagnostics.DiagnosticsCache
import dev.okhsunrog.vpnhide.diagnostics.LayerStatus
import dev.okhsunrog.vpnhide.diagnostics.Verdict
import dev.okhsunrog.vpnhide.diagnostics.buildDiagnosticReport
import dev.okhsunrog.vpnhide.diagnostics.classifyKpmProblem
import dev.okhsunrog.vpnhide.diagnostics.renderKpmProblem
import dev.okhsunrog.vpnhide.diagnostics.standaloneKpmLoaded
import dev.okhsunrog.vpnhide.diagnostics.token
import dev.okhsunrog.vpnhide.diagnostics.verdict
import dev.okhsunrog.vpnhide.generated.HookIds
import dev.okhsunrog.vpnhide.hook.HookEntry
import dev.okhsunrog.vpnhide.picker.parseTargetsSnapshot
import dev.okhsunrog.vpnhide.settings.SettingsRepository
import dev.okhsunrog.vpnhide.settings.filesystemHidingDashboardMessage
import dev.okhsunrog.vpnhide.settings.installedNativeOptionalHooks
import dev.okhsunrog.vpnhide.startup.StartupTrace
import kotlinx.coroutines.flow.first
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import dev.okhsunrog.vpnhide.diagnostics.DiagnosticGate
import dev.okhsunrog.vpnhide.diagnostics.DiagnosticsCache
import dev.okhsunrog.vpnhide.diagnostics.LayerStatus
import dev.okhsunrog.vpnhide.diagnostics.RoutingGateCache
import dev.okhsunrog.vpnhide.diagnostics.Verdict
import dev.okhsunrog.vpnhide.diagnostics.VpnTransportWatcher
import dev.okhsunrog.vpnhide.diagnostics.blockedOrNull
import dev.okhsunrog.vpnhide.diagnostics.verdict
import dev.okhsunrog.vpnhide.settings.LocalSettingsInteractor
import dev.okhsunrog.vpnhide.settings.LocalSettingsState
import dev.okhsunrog.vpnhide.settings.SettingsRepository
Expand All @@ -46,6 +54,8 @@ import dev.okhsunrog.vpnhide.ui.components.EnhancedOutlinedButton
import dev.okhsunrog.vpnhide.ui.components.GroupedCard
import dev.okhsunrog.vpnhide.ui.components.IconBubble
import dev.okhsunrog.vpnhide.ui.components.MetricTile
import dev.okhsunrog.vpnhide.ui.components.SectionHeader
import dev.okhsunrog.vpnhide.ui.components.container
import dev.okhsunrog.vpnhide.ui.components.pulse
import dev.okhsunrog.vpnhide.ui.theme.AppColors
import kotlinx.coroutines.Dispatchers
Expand Down
Loading