# Wrapper Android propio Proyecto Gradle para construir la APK de la rama sin depender del APK oficial como molde. ## Por que existe El APK que se venia usando es el de epsylon re-firmado, y su `classes.dex` **no implementa `WebChromeClient.onPermissionRequest`**. Sin ese metodo el WebView de Android deniega por defecto toda peticion de `getUserMedia()`, de modo que las videollamadas de Karvan no pueden funcionar por mucho que se parchee el manifest: la lista de permisos es estatica y hay que declararla al compilar. Este wrapper resuelve las dos puertas: declara los permisos y los concede al contenido web solo tras el consentimiento del usuario. ## Permisos: declarados, no concedidos `CAMERA`, `RECORD_AUDIO` y `MODIFY_AUDIO_SETTINGS` figuran en el manifest porque Android exige que la lista sea fija. Pero son permisos peligrosos: **se piden en tiempo de ejecucion la primera vez que se pulsa Llamar**, no al instalar. Si nadie llama, no se pide nada y la app no accede a la camara ni al microfono. `uses-feature ... required="false"` evita excluir de la tienda a dispositivos sin camara o sin microfono. ## Que reutiliza y que es nuevo Las tres librerias nativas se toman tal cual del APK existente: - `libnode.so` — nodejs-mobile **v18.20.4** oficial (OpenSSL 3.0.13+quic), un artefacto publico; no hay que compilar Node. - `libnative-lib.so` — 6,8 KB, un solo simbolo JNI: `Java_com_solarnethub_oasis_OasisActivity_startNodeWithArguments`. - `libc++_shared.so` Por eso el `namespace` del modulo es `com.solarnethub.oasis`: JNI resuelve por nombre y la clase puente tiene que vivir en ese paquete. El `applicationId` si es propio (`net.laenre.oasis`), asi que la app se instala junto a la oficial sin pisarla. Si algun dia se quiere soltar el `.so` de epsylon, reimplementar esos 6,8 KB son unas 40 lineas de C++ contra las cabeceras de nodejs-mobile, y ahi si haria falta el NDK. ## Mejoras sobre el APK actual - `targetSdk 35` (el actual se quedo en uno ya caducado para la tienda). - Trafico en claro permitido **solo hacia loopback** via `network_security_config`, en vez de `usesCleartextTraffic="true"` global. - `allowBackup="false"`: `adb backup` deja de poder extraer `~/.ssb`. - El backend corre en un servicio en primer plano, en el proceso `:node`, asi que sobrevive en segundo plano — imprescindible para recibir llamadas. El APK actual declara `FOREGROUND_SERVICE` pero no registra ningun servicio. - Al descomprimir el backend se descartan las entradas con rutas sospechosas (zip slip). ## Construir ```sh # 1. dependencias del backend (una vez) (cd ../src/server && npm install) # 2. librerias nativas + empaquetado del backend ./scripts/prepare.sh ../../oasis_mobile # o la ruta de un APK # 3. compilar ./gradlew assembleDebug # o assembleRelease ``` Para firmar la release, por entorno (la keystore nunca al repositorio): ```sh export OASIS_KEYSTORE=/ruta/oasis-alfa-key.jks export OASIS_KEYSTORE_PASS=... export OASIS_KEY_ALIAS=oasis ./gradlew assembleRelease ``` ## Requisitos JDK 17 o superior **con compilador**. El OpenJDK del sistema puede ser solo runtime; `gradle.properties` apunta al JDK que trae Android Studio. Cambia esa linea si compilas en otra maquina. ## Estado Compila y genera APK con los permisos y el `onPermissionRequest` en su sitio. **Falta probarlo en un dispositivo real**: que arranque el backend, que la interfaz cargue y que `getUserMedia` resuelva al pulsar Llamar.