Files
DataControl/app/src/main/java/com/jttools/datacontrol/data/AppSettings.kt
T
tuxgyverandClaude Opus 4.8 d4aa0e1962 feat: partage d'écran Android 5+ (MediaProjection) et blocage des installations
- Partage d'écran par MediaProjection (ScreenCaptureService + ScreenConsentActivity)
  quand la capture par accessibilité n'est pas possible (Android < 11 ou service coupé).
  En mode propriétaire, le service d'accessibilité valide seul le consentement système.
- Blocage de l'installation d'applications (Play Store compris) piloté par le parent
  (policy block_installs → OwnerPolicy DISALLOW_INSTALL_APPS en mode propriétaire).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R9CBCVP5oDu2sfoYPisNCQ
2026-10-25 22:28:16 +01:00

69 lines
2.7 KiB
Kotlin

package com.jttools.datacontrol.data
import com.jttools.datacontrol.remote.FamilyLink
import java.time.LocalDate
/**
* Réglages persistés de l'application, avec leurs valeurs par défaut.
*/
data class AppSettings(
/** Tunnel WireGuard vers le serveur familyd monté en permanence (désactivation protégée par mot de passe). */
val controlEnabled: Boolean = false,
val planLimitMo: Long = 1000L,
val planPriceEuro: Double = 19.99,
val overagePricePerMoEuro: Double = 0.01,
val planStartDateEpochDay: Long = LocalDate.now().toEpochDay(),
val autoResetEnabled: Boolean = true,
val baselineMobileBytesAtReset: Long = 0L,
val passwordHash: String? = null,
val passwordSalt: String? = null,
/** Règles d'usage des applications (plages horaires, limites, interdites), envoyées par le serveur. */
val rulesJson: String? = null,
/** Liaison avec le serveur familyd (null tant que l'appareil n'est pas associé). */
val link: FamilyLink? = null,
/** Mode réseau appliqué par le serveur : open, allowlist ou cut. */
val serverMode: String = "open",
val serverModeReason: String = "",
val policyVersion: Long = 0L,
/** Bloque l'installation d'applications (Play Store compris) — appliqué en mode propriétaire. */
val blockInstalls: Boolean = false,
/** Téléphone verrouillé à distance par le parent : un code du serveur est exigé pour le déverrouiller. */
val parentalLocked: Boolean = false
) {
val isPaired: Boolean get() = link != null
val planStartDate: LocalDate get() = LocalDate.ofEpochDay(planStartDateEpochDay)
/** Un mot de passe de verrouillage protège la désactivation du contrôle et l'accès aux réglages. */
val hasPassword: Boolean get() = !passwordHash.isNullOrEmpty()
/** Prochaine date de réinitialisation automatique (anniversaire mensuel du début de forfait). */
fun nextAutoResetDate(): LocalDate {
var next = planStartDate.plusMonths(1)
val today = LocalDate.now()
while (!next.isAfter(today)) {
next = next.plusMonths(1)
}
return next
}
}
/** État calculé de la consommation, dérivé des réglages + de la mesure de données réelle. */
data class UsageState(
val consumedMo: Long,
val planLimitMo: Long,
val overageMo: Long,
val isOverPlan: Boolean,
val estimatedTotalPriceEuro: Double
) {
val percentOfPlan: Float
get() = if (planLimitMo <= 0) 0f else (consumedMo.toFloat() / planLimitMo.toFloat()).coerceAtLeast(0f)
}
enum class DataState {
OK, // sous le seuil d'alerte
WARNING, // proche ou au-delà du forfait (>= 80 %)
CUT, // le serveur coupe l'accès (mode « coupé » ou « liste blanche »)
WIFI // Wi-Fi actif
}