release: v0.1.6 — retire le bouton de test VPN, README à jour

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
tuxgyverandClaude Sonnet 5 committed 2026-09-20 18:48:53 +02:00
1 parent 790397da0e
commit d7e55dbb91
5 files changed
+35 -43

No files matched your search

+5
View File
@@ -1,5 +1,10 @@
# Changelog
## v0.1.6 – 2026-09-20
- Onglet Journal : le bouton « Tester le VPN » est retiré (le VPN se monte correctement).
- README mis à jour (journal, contrôle parental, permissions, architecture).
## v0.1.5 – 2026-09-20
- Onglet Journal : bouton **Tester le VPN** (10 s) qui monte le tunnel quel que soit le réseau, pour savoir si le VPN peut se monter sur l'appareil ; les erreurs de démarrage du service VPN sont désormais tracées au lieu d'être silencieuses.
+26 -3
View File
@@ -2,7 +2,7 @@
**DataControl** est une application Android qui surveille en arrière-plan la consommation de données mobiles et coupe automatiquement l'accès à Internet en cas de dépassement du forfait — sans jamais toucher au Wi-Fi.
> JT-Tools by Johnny — v0.1.0
> JT-Tools by Johnny — version courante et historique : voir [CHANGELOG.md](CHANGELOG.md) (aussi lisible dans l'onglet *À propos* de l'application).
---
@@ -16,7 +16,23 @@
- **Coupure cyclique en cas de dépassement** — Une fois le forfait dépassé, une coupure totale (même pour la liste blanche) se déclenche automatiquement toutes les X minutes (paramétrable), pendant une courte pulsation, avant de revenir en mode "liste blanche seule".
- **Notification permanente** — Affiche la consommation (Mo / forfait / %), l'état des données avec un code couleur (🟢 sous le forfait, 🟠 proche du forfait, 🔴 hors-forfait/coupure, 🔵 Wi-Fi actif), et le coût estimé. Rafraîchie toutes les 20 secondes et à chaque changement de réseau.
- **Démarrage au boot** — Le service redémarre automatiquement après un redémarrage de l'appareil si le contrôle était actif.
- **Interface Material 3** — Thème clair/sombre avec couleurs dynamiques (Android 12+), 3 écrans : Tableau de bord, Réglages, Liste blanche.
- **Alerte pare-feu inactif** — Si le contrôle est actif sur données mobiles mais que le tunnel VPN n'est pas monté, la notification passe en rouge (« PARE-FEU INACTIF ») : les données ne sont alors pas filtrées.
- **Journal de diagnostic** — Onglet *Journal* : état du VPN en direct, décisions du pare-feu, et, avec le service d'accessibilité, chaque application utilisée avec son verdict réseau/lancement. Conservé 15 jours.
- **Mise à jour intégrée** — Recherche et installation de la dernière Release Gitea depuis l'onglet *À propos*.
- **Mot de passe de verrouillage** — Protège les Réglages et la désactivation du contrôle.
- **Interface Material 3** — Thème clair/sombre avec couleurs dynamiques (Android 12+), 5 onglets : Tableau de bord, Réglages, Liste blanche, Journal, À propos.
---
## Contrôle parental (avec FamilyControl)
DataControl peut être associé à **FamilyControl** (application parent en TypeScript/Expo, dépôt séparé) via Firebase (Auth + Firestore). Sans fichier `firebase.properties` à la compilation (voir `firebase.properties.example`), ces fonctions sont simplement désactivées.
- **Appairage** par code à usage court, saisi dans *Réglages → Contrôle parental*.
- **Remontées** : batterie, position, état du pare-feu, consommation, trafic quotidien mobile/Wi-Fi, temps d'écran, événements (VPN révoqué, protection retirée…).
- **Consignes du parent** : contrôle activé/désactivé, applications autorisées (mobile et Wi-Fi), filtrage Wi-Fi.
- **Règles d'usage** (service d'accessibilité) : plages horaires (avec coupure optionnelle des données mobiles hors plage), temps d'écran quotidien global ou par application, ajout de temps, applications interdites. Le lanceur, le téléphone, le clavier et DataControl ne sont jamais bloqués.
- **Anti-désinstallation** par administrateur d'appareil (retirable depuis les Réglages Android : le parent est alors alerté ; le mot de passe protège le retrait depuis l'application).
---
@@ -44,6 +60,9 @@ Le pare-feu est démarré/arrêté automatiquement selon le transport réseau ac
| Ignorer l'optimisation de la batterie | Éviter que le système ne tue le service de surveillance |
| `QUERY_ALL_PACKAGES` | Lister toutes les applications installées dans l'écran Liste blanche |
| `RECEIVE_BOOT_COMPLETED` | Relancer la surveillance après redémarrage si le contrôle était actif |
| Position (dont arrière-plan) | Facultatif — transmise au parent si l'appareil est associé |
| Administrateur d'appareil | Facultatif — anti-désinstallation |
| Service d'accessibilité | Facultatif — détecte l'application au premier plan (sans lire les écrans) pour les règles d'usage et le journal |
---
@@ -60,7 +79,10 @@ Le pare-feu est démarré/arrêté automatiquement selon le transport réseau ac
- **Kotlin + Jetpack Compose (Material 3)**, Hilt pour l'injection de dépendances.
- `data/` — `SettingsRepository` (DataStore Preferences), `UsageRepository` (TrafficStats), `InstalledAppsRepository` (PackageManager).
- `service/` — `FirewallVpnService` (VpnService), `ConnectivityObserver` (détection Wi-Fi/cellulaire), `DataMonitorService` (orchestration + notification), `MonitorStateHolder` (pont service ↔ UI), `BootReceiver`.
- `ui/` — écrans Compose (`dashboard`, `settings`, `whitelist`), navigation par `NavigationBar`, thème dynamique.
- `remote/` — `FirebaseGateway`, `RemoteSync` (appairage, consignes, remontées), `DeviceReporter` (batterie, position, trafic, état).
- `guard/` — `GuardEngine` (règles d'usage, temps d'écran), `AppGuardService` (accessibilité), `BlockedActivity`.
- `admin/` — administrateur d'appareil (anti-désinstallation). `log/` — journal de diagnostic.
- `ui/` — écrans Compose (`dashboard`, `settings`, `whitelist`, `journal`, `about`, `family`), navigation par `NavigationBar`, thème dynamique.
---
@@ -70,6 +92,7 @@ Le pare-feu est démarré/arrêté automatiquement selon le transport réseau ac
make build # APK debug
make release # APK release signé, copié en DataControl-<version>.apk
make install # Installe le debug sur un appareil connecté (adb)
make deploy # APK release + publication en Release Gitea (voir `make help`)
```
Prérequis : Android SDK (API 34), JDK 17. Le wrapper Gradle télécharge Gradle 8.13 au premier lancement.
@@ -23,7 +23,6 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
@@ -34,14 +33,11 @@ import androidx.compose.ui.unit.sp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.jttools.datacontrol.log.AppLog
import com.jttools.datacontrol.service.FirewallVpnService
import com.jttools.datacontrol.ui.SystemActions
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@Composable
fun JournalScreen(systemActions: SystemActions) {
fun JournalScreen() {
val context = LocalContext.current
val scope = rememberCoroutineScope()
val entries by AppLog.entries.collectAsStateWithLifecycle()
// État en direct du pare-feu, rafraîchi chaque seconde : première chose à regarder si le VPN n'apparaît pas.
@@ -67,18 +63,6 @@ fun JournalScreen(systemActions: SystemActions) {
}) { Text("Partager") }
OutlinedButton(onClick = { AppLog.clear() }) { Text("Effacer") }
}
Button(onClick = {
scope.launch {
if (!FirewallVpnService.isPrepared(context)) {
AppLog.i("Test VPN", "autorisation VPN absente : demande à l'utilisateur")
systemActions.requestVpnPermission { granted ->
AppLog.i("Test VPN", "autorisation VPN ${if (granted) "accordée" else "REFUSÉE"} — relancez le test")
}
return@launch
}
runVpnTest(context)
}
}, modifier = Modifier.fillMaxWidth()) { Text("Tester le VPN (10 s, coupe les autres applications)") }
LazyColumn(Modifier.fillMaxWidth().weight(1f), verticalArrangement = Arrangement.spacedBy(2.dp)) {
items(entries.asReversed()) { line ->
val color = when {
@@ -99,23 +83,3 @@ private fun liveStatus(context: Context): String = buildString {
appendLine("Conservation du journal : ${AppLog.RETENTION_DAYS} jours")
append("Attendu : le tunnel n'est monté QUE sur données mobiles, contrôle activé.")
}
/** Monte le tunnel 10 s quel que soit le réseau : prouve (ou infirme) que le VPN peut se monter sur cet appareil. */
private suspend fun runVpnTest(context: Context) {
val app = context.applicationContext
AppLog.i("Test VPN", "démarrage : demande de montage du tunnel (mode blocage total)")
try {
androidx.core.content.ContextCompat.startForegroundService(app, FirewallVpnService.startBlockAllIntent(app))
} catch (e: Exception) {
AppLog.e("Test VPN", "le service VPN n'a pas pu démarrer", e)
return
}
delay(3_000)
if (FirewallVpnService.tunnelActive) AppLog.i("Test VPN", "SUCCÈS : tunnel monté — l'icône clé doit être visible")
else AppLog.e("Test VPN", "ÉCHEC : tunnel non monté après 3 s (voir les lignes FirewallVpnService ci-dessus)")
delay(7_000)
runCatching {
androidx.core.content.ContextCompat.startForegroundService(app, FirewallVpnService.stopIntent(app))
}
AppLog.i("Test VPN", "fin du test : tunnel arrêté")
}
@@ -75,7 +75,7 @@ fun DataControlNavHost(systemActions: SystemActions) {
composable(Destination.Dashboard.route) { DashboardScreen(systemActions) }
composable(Destination.Settings.route) { SettingsScreen(systemActions) }
composable(Destination.Whitelist.route) { WhitelistScreen() }
composable(Destination.Journal.route) { JournalScreen(systemActions) }
composable(Destination.Journal.route) { JournalScreen() }
composable(Destination.About.route) { AboutScreen() }
}
}
+2 -2
View File
@@ -1,2 +1,2 @@
versionName=0.1.5
versionCode=6
versionName=0.1.6
versionCode=7