--- name: android-release description: Gerar, testar na TV e publicar o Nuvio nativo para Android TV / Google TV (.apk, host SDL2 + Media3 em android/, nucleo C com -DNV_ANDROID). Use para qualquer build .apk, release ou preview Android, auto-atualizacao do Android, ou mudanca em android/, src/android.c, src/video_android.c, NvPlayer.kt, ParaleloDataSource.kt. --- # Android TV (.apk) Passagem para quem faz a release: `docs/android/RELEASE.md`. Mesmo nucleo C da LG e da Samsung; so a camada de plataforma muda: | Peca | Onde | |---|---| | Activity (ambiente, teclas, despedida, instalar APK) | `android/app/src/main/java/space/nuvio/nativelegacy/NuvioActivity.kt` | | Player (Media3 1.8 + FFmpeg de audio da Jellyfin) | `NvPlayer.kt` + `src/video_android.c` (mesma ABI de eventos do `.tpk`) | | Video em 4 conexoes (janela TCP do Android) | `ParaleloDataSource.kt` | | `[tv]`, logcat, pilha de 8 MB, superficie 4K, instalador | `src/android.c` | | curl + mbedTLS, libjpeg-turbo, libwebp (.so para o dlopen) | `tools/android/deps.sh` -> `~/.cache/nuvio-android/prefix` | | Build (debug + release) | `tools/android.sh` | | Release | `tools/release-android.sh` | Android 7+ (minSdk 24), arm64-v8a + armeabi-v7a. Muita TV (a TCL do dono) so roda 32 bits: as duas ABIs vao sempre. ## Ambiente do Mac - JDK 17 em `~/.local/jdks/jdk-17*` (o cask do Homebrew pede sudo); SDK em `~/Library/Android/sdk` (NDK 27.2.12479018, cmake 3.22.1, build-tools 35). - Primeira vez numa maquina: `bash tools/android/deps.sh` (curl+mbedTLS com `MBEDTLS_THREADING_C` — sem ela o app cai com "Scudo race on chunk header"). - Chave de release: `~/.nuvio-android/release.jks` + `release.env` (chmod 600, copia no Vaultwarden). O `android.sh` e o `release-android.sh` leem sozinhos. CERT SHA-256 fixado no `release-android.sh`. PERDER A CHAVE = ninguem atualiza por cima. ## TV de teste do dono TCL Smart TV Pro, Android 14, so 32 bits, Mali-G52, `adb connect 192.168.1.128:5555` (depuracao de rede; se recusar, a depuracao desligou: pedir para religar e autorizar). Na TV esta o APK de RELEASE (assinatura nova): build debug por cima exige desinstalar. - Log do app inteiro: `adb shell "run-as space.nuvio.nativelegacy cat files/dados/nuvio.log"` (e `nuvio-anterior.log`). So funciona com APK debuggable; no release, use o envio de log do app (D1, `plataforma` `android`). - logcat da TCL tem 256 KB e roda em segundos: `adb logcat -G 16M` antes. - Captura de tela NAO pega o video (plano de hardware); geometria do video: `adb shell dumpsys SurfaceFlinger` (Disp Frame / Source Crop). - Instalar por cima sem o modo seguro desfazer ajustes: `adb shell input keyevent HOME` antes do `adb install -r` (o onStop grava a despedida). ## Armadilhas ja pagas (nao refazer) - SDLActivity sem `SDL_HIDAPI` crasha; hidapi e C++ -> `ANDROID_STL=c++_static`. - Pilha: SDLThread nasce com 16 MB (filtro na copia do SDLActivity no Gradle) e todo `pthread_create` do nucleo passa por `--wrap` com 8 MB. O bionic da ~1 MB e o guia de TV estourava. - Home/troca de app mata o processo sem saida limpa: `dados/despedida.txt` ("oculto") no onStop, senao o modo seguro desfaz tema/vidro/4K. - Plano de video da TCL PRENDE a primeira geometria e so liga HDR/DV quando a Surface nasce com o decoder ja em HDR: o NvPlayer recria a Surface (GONE -> VISIBLE) no primeiro quadro HDR e nas trocas de aspecto (juntadas em 350 ms). TextureView foi tentado e recusado: perde HDR. - Janela lisa (`video_janela`) ENCAIXA com tarja; recorte (`video_janela_fonte`) e exato. - Decoder DV da MediaTek: `c2.mtk.dvhe.*` / `c2.mtk.dvav.*` (sem "dolby"). - 18 Mbps no teste de velocidade = janela TCP por conexao do Android (tcp_rmem max 2 MB, ~20 Mbps a 250 ms do debrid). Por isso o video e o teste usam 4 conexoes. Redirecionamento do AIOStreams troca de protocolo: o ParaleloDataSource segue o 302 a mao. - Interface 4K: a TCL concede 3840x2160 mas a Mali-G52 cai para 13-48 fps e nao se ve diferenca: desligada e escondida no Android. Trailer da Apple limitado a 1080p (4K travou a UI 20 s). - CH+/CH-: com canal na tela trocam canal; fora disso CH+ = AZUL (Salvos) e CH- = registro (`app_zap_ativo`, main.c). ## Release (dentro do vX.Y.Z normal) 1. Versao como sempre (`deploy/app/appinfo.json` + `tools/tizen-config.xml`). 2. Worktree limpa no commit da release e: ```bash bash tools/release-android.sh ``` Sai `build/release-/Nuvio--android.apk` + `SHA256SUMS-android`. Recusa arvore suja, versao divergente, chave errada/ausente, arquivo de pessoa e lib faltando. 3. Junto da LG e da Samsung (skill `samsung-release`): `SHA256SUMS` une os tres e o `.apk` vai no MESMO `gh release create vX.Y.Z`. Sem ele no latest, nenhum Android se atualiza sozinho (o app procura `-android.apk` em `releases/latest`). 4. Enquanto o dono nao liberar a divulgacao do Android: o `.apk` entra como anexo, SEM linha na tabela "Which file do I need?", sem aviso no app (`avisos.json` plataforma `android`) e sem README. Quando liberar, a linha e: `| Android TV / Google TV | Android 7 or newer | \`Nuvio-X.Y.Z-android.apk\` |` ## Previews (fora do vX.Y.Z) `gh release create android-preview.N --prerelease --latest=false` com o APK renomeado `Nuvio--android-preview.N.apk` (o nome com "preview" nunca casa com a auto-atualizacao). Substituir o anexo de uma preview existente: `git tag -f` + `git push -f origin refs/tags/android-preview.N`, `gh release delete-asset` + `gh release upload`, e atualizar o SHA-256 das notas. Nunca marcar preview como latest. ## Auto-atualizacao `src/atualizacao.c` (`acharApk`, `fioInstalarApk`) + `NuvioActivity.instalarApk` (FileProvider + ACTION_VIEW). Primeira vez a TV pede "permitir instalar apps desta fonte" e o cartao pede para tentar de novo. So funciona entre APKs com a MESMA chave. Prova de ponta a ponta: TV com o release N, publicar N+1 como latest com o `-android.apk`, "Atualizar agora".