feat: actions à distance du parent (voir l'écran, verrouiller/veille, couper le son)

- Partage d'écran par le service d'accessibilité (Android 11+), image réduite envoyée dans le tunnel
- Bandeau « Écran partagé avec le parent » visible pendant tout le partage, arrêt auto après 5 min
- Verrouillage/mise en veille (lockNow, force-lock) et coupure/rétablissement du son
- Boucle de commandes en attente longue via /api/device/commands

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R9CBCVP5oDu2sfoYPisNCQ
This commit is contained in:
tuxgyverandClaude Opus 4.8 committed 2026-10-25 15:07:48 +01:00
1 parent e6215ab4a7
commit 7af250cc1c
12 files changed
+288 -10

No files matched your search

@@ -38,6 +38,16 @@ class FamilyApi(private val apiBase: String, private val token: String) {
request("POST", "$apiBase/api/device/apps", token, JSONObject().put("apps", apps))
}
/** Attente longue des commandes du parent (verrouillage, son, partage d'écran). */
fun commands(waitSeconds: Int): JSONArray =
JSONObject(request("GET", "$apiBase/api/device/commands?wait=$waitSeconds", token, null, waitSeconds * 1000 + 5000))
.optJSONArray("commands") ?: JSONArray()
/** Envoie une image de l'écran (JPEG) pendant un partage. */
fun screen(jpeg: ByteArray) {
request("POST", "$apiBase/api/device/screen", token, jpeg, "image/jpeg")
}
companion object {
private const val CONNECT_TIMEOUT_MS = 10_000
private const val READ_TIMEOUT_MS = 15_000
@@ -50,24 +60,31 @@ class FamilyApi(private val apiBase: String, private val token: String) {
return request("POST", "${serverUrl.trimEnd('/')}/api/pair", null, body)
}
fun request(method: String, url: String, token: String?, body: JSONObject?): String {
fun request(method: String, url: String, token: String?, body: JSONObject?, readTimeoutMs: Int = READ_TIMEOUT_MS): String {
return request(method, url, token, body?.toString()?.toByteArray(Charsets.UTF_8),
"application/json; charset=utf-8", readTimeoutMs)
}
fun request(method: String, url: String, token: String?, body: ByteArray?, contentType: String,
readTimeoutMs: Int = READ_TIMEOUT_MS): String {
val conn = try {
(URL(url).openConnection() as HttpURLConnection).apply {
requestMethod = method
connectTimeout = CONNECT_TIMEOUT_MS
readTimeout = READ_TIMEOUT_MS
readTimeout = readTimeoutMs
setRequestProperty("Accept", "application/json")
token?.let { setRequestProperty("Authorization", "Bearer $it") }
if (body != null) {
doOutput = true
setRequestProperty("Content-Type", "application/json; charset=utf-8")
setRequestProperty("Content-Type", contentType)
setFixedLengthStreamingMode(body.size)
}
}
} catch (e: IOException) {
throw ApiException(0, "Serveur injoignable : ${e.message}")
}
try {
if (body != null) conn.outputStream.use { it.write(body.toString().toByteArray(Charsets.UTF_8)) }
if (body != null) conn.outputStream.use { it.write(body) }
val code = conn.responseCode
val text = (if (code in 200..299) conn.inputStream else conn.errorStream)
?.bufferedReader()?.use { it.readText() }.orEmpty()