Revisado en el emulador: la APK oficial 1.3.3 del dev pide microfono y camara y trae un puente nativo (.audio_bridge) que graba, reproduce, saca la camara y emite. Nuestra app Android no lo tiene, asi que en esta APK el Telefono dice que no hay llamadas. - README, guia, android/README y los dos esquemas lo cuentan asi - SSB_server.js queda identico al de la APK oficial (su version de movil enchufa ya phone_*_android.js); fuera el enganche duplicado de main.js - el aviso de bienvenida va encima del lanzador: en el primer arranque quedaba a 1.300px y no se veia
98 lines
3.9 KiB
Markdown
98 lines
3.9 KiB
Markdown
# 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. Esta app
|
|
aun no lo tiene. 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:
|
|
|
|
```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.
|