OASIS_MOBILE/android/README.md
hacklab 6bacafea64 android: la APK se monta sobre la oficial del dev
La app Android de epsylon trae desde la 1.3.x un puente nativo de audio y
camara (.audio_bridge) para el Telefono y las Salas, y no tiene el codigo
publicado. android/scripts/sobre_oficial.sh coge su APK de la misma version,
le cambia el backend por el de la rama (con su node_modules), le pone el
paquete net.laenre.oasis (y los authorities, el permiso propio y las acciones
de llamada) para que conviva con la oficial, y la monta y firma. apktool va
con version y huella fijas.

Probado en el emulador: el Telefono ofrece llamadas y en una sala el
microfono graba y se corta al salir. README, guia, android/README y los
esquemas lo cuentan; el proyecto Gradle propio queda sin uso.
2026-10-19 14:12:18 +02:00

4 KiB

Wrapper Android propio

Proyecto Gradle para construir la APK de la rama sin depender del APK oficial como molde.

Por que existe

Nota (19/10/2026): desde la 1.3.x la APK oficial ya pide microfono y camara y trae un puente nativo de audio y camara (.audio_bridge) para el Telefono y las Salas. Por eso la APK de la rama se monta ahora sobre la oficial con scripts/sobre_oficial.sh, y el proyecto Gradle de esta carpeta queda sin uso. Lo de abajo describe la situacion anterior.

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 llamadas 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

Con Android Studio basta con ./scripts/android-studio.sh: clona el Oasis oficial, descarga su APK de la misma version y empaqueta el backend. Luego File > Open > esta carpeta y Build > Build APK(s). A mano, paso a paso:

# 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):

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.