# Integración Videollamadas — Juphoon jc_sdk ## Estado general | Fase | Estado | |---|---| | 1. SDK wrapper (`videocall_sdk`) | ✅ Completado | | 2. Configuración nativa (permisos) | ✅ Completado | | 3. Configuración por entorno (AppKey) | ✅ Completado | | 4. Feature videocall (UI + lógica) | ⏳ Pendiente | | 5. Pruebas APP↔APP | ⏳ Pendiente | | 6. Integración con backend (señalización) | ⏳ Pendiente | | 7. Pruebas APP↔Reloj | ⏳ Pendiente | | 8. Token auth (producción) | ⏳ Pendiente | | 9. Push/background iOS | ⏳ Pendiente (sin doc del proveedor) | | 10. Chat | ⏳ Pendiente (sin spec del proveedor) | --- ## Fase 1: SDK wrapper — ✅ Paquete `packages/videocall_sdk/` con wrap 100% de `jc_sdk` v2.16.5. ### Arquitectura (patrón sca_treezor) - Constructor injection (no singletons estáticos) - GetIt module (`videocallSdkModule(config)`) - `VideocallSdkManager` orquestador de inicialización - `VideocallSdkConfig` abstracto para config por entorno - Riverpod providers + StreamProviders para UI reactiva - Callbacks del SDK → Dart Streams ### Servicios (7 total, cobertura 100%) - `VideocallClient` → JCClient (auth, login, logout, messaging) - `VideocallCallService` → JCCall (llamadas 1-to-1) - `VideocallDeviceService` → JCMediaDevice (cámara, mic, speaker) - `VideocallChannelService` → JCMediaChannel (llamadas grupales) - `VideocallPushService` → JCPush (push notifications) - `VideocallNetService` → JCNet (estado de red) - `VideocallLogService` → JCLog (logging) ### Estructura ``` packages/videocall_sdk/lib/src/ ├── config/videocall_sdk_config.dart ├── di/videocall_sdk_module.dart ├── manager/videocall_sdk_manager.dart ├── models/ (call_state, call_direction, videocall_item, etc.) ├── services/ (7 servicios) └── providers/videocall_providers.dart ``` --- ## Fase 2: Permisos nativos — ✅ ### Android (`AndroidManifest.xml`) - [x] INTERNET (ya existía) - [x] ACCESS_NETWORK_STATE (ya existía) - [x] ACCESS_WIFI_STATE - [x] CAMERA (ya existía) - [x] RECORD_AUDIO - [x] MODIFY_AUDIO_SETTINGS - [x] BLUETOOTH - [x] uses-feature: hardware.camera - [x] uses-feature: hardware.camera.autofocus - [x] uses-feature: hardware.bluetooth (optional) ### Android (`proguard-rules.pro`) - [x] -keep com.juphoon.** - [x] -keep com.justalk.** - [x] -keepattributes InnerClasses ### iOS (`Info.plist`) - [x] NSCameraUsageDescription (actualizado: QR + videollamadas) - [x] NSMicrophoneUsageDescription - [x] NSPhotoLibraryUsageDescription ### iOS (`Podfile`) - [x] PERMISSION_CAMERA=1 - [x] PERMISSION_PHOTOS=1 - [x] PERMISSION_MICROPHONE=1 --- ## Fase 3: Config por entorno — ✅ - [x] `juphoonAppKey` en development.json, staging.json, production.json - [x] `Environment.juphoonAppKey` via `String.fromEnvironment()` - [x] `SaveFamilyVideocallConfig` implementa `VideocallSdkConfig` - [x] `videocallSdkModule(config)` llamado en `init_app.dart` - [ ] AppKeys separadas por entorno (por ahora las 3 usan la misma clave de dev) --- ## Fase 4: Feature videocall — ⏳ SIGUIENTE Feature en `modules/legacy/modules/device_management/lib/src/features/videocall/` ### Por hacer - [ ] `videocall_builder.dart` — GoRouter builder - [ ] `domain/entities/videocall_entity.dart` — Freezed entity - [ ] `domain/entities/videocall_error.dart` — Error enum con i18n - [ ] `presentation/state/videocall_view_model.dart` — Notifier - [ ] `presentation/state/videocall_view_state.dart` — Freezed state - [ ] `presentation/videocall_screen.dart` — Pantalla de llamada - [ ] `presentation/widgets/local_video_view.dart` — Video local - [ ] `presentation/widgets/remote_video_view.dart` — Video remoto - [ ] `presentation/widgets/call_controls.dart` — Botones (colgar, mute, cámara) - [ ] `presentation/widgets/incoming_call_dialog.dart` — Dialog llamada entrante - [ ] Providers en `core/providers/` - [ ] Ruta en GoRouter (`app_router.dart`) - [ ] Runtime permissions (pedir cámara/mic en runtime) --- ## Fase 5: Pruebas APP↔APP — ⏳ - [ ] Login con 2 userIDs de prueba (`p_test1`, `p_test2`) - [ ] Llamada de voz APP→APP - [ ] Videollamada APP→APP - [ ] Responder llamada entrante - [ ] Rechazar llamada - [ ] Colgar durante llamada - [ ] Mute/unmute micrófono - [ ] Cambiar cámara frontal/trasera - [ ] Speaker on/off - [ ] Llamada perdida (onMissedCallItem) - [ ] Verificar desfase versión SDK (quickstart 1.0.2 vs pub.dev 2.16.5) --- ## Fase 6: Integración backend — ⏳ - [ ] Obtener documentación API REST del backend SaveFamily para señalización - [ ] Endpoint para iniciar llamada → notificar al reloj - [ ] Endpoint para recibir notificación de llamada entrante del reloj - [ ] Formato userID definido con backend (`p_` vs `w_`) - [ ] Sanitización de emails (@ → _ en userIDs) --- ## Fase 7: Pruebas APP↔Reloj — ⏳ - [ ] Llamada APP → Reloj - [ ] Llamada Reloj → APP - [ ] Videollamada grupal (JCMediaChannel) - [ ] Límite 5 min de llamada - [ ] Registro IMEI (protocolo RYIMEI) — lo hace el backend --- ## Fase 8: Token auth — ⏳ - [ ] Backend implementa generación de tokens Juphoon (usa AppSecret) - [ ] App pide token al backend antes del login - [ ] Token se pasa como `password` en `VideocallClient.login()` - [ ] Activar Token鉴权 en consola Juphoon (ya está activo) Nota: para dev/testing no es necesario — `autoCreateAccount = true` en LoginParam permite login con cualquier password. --- ## Fase 9: Push/Background iOS — ⏳ RIESGO **Problema:** No hay documentación de cómo recibir llamadas con la app cerrada en iOS. - [ ] Probar qué pasa cuando la app está cerrada y llega una llamada (fase 5) - [ ] Si no funciona: investigar PushKit + CallKit - [ ] Verificar si `JCPush` del SDK resuelve esto - [ ] Consultar pestaña "消息通知服务" en la consola Juphoon - [ ] Si es deal-breaker: escalar antes del pago ($8,835) --- ## Fase 10: Chat — ⏳ SIN SPEC - [ ] Obtener especificación del módulo de chat del proveedor - [ ] Determinar si usa JCMediaChannel (SDK) o API propia - [ ] $2,950 pagados sin lista de features --- ## Credenciales Juphoon Cloud | Campo | Valor | Quién lo usa | |---|---|---| | AppKey | `9efcf2d889dc8a0320925096` | App Flutter + Backend | | AppSecret | `ui7pr73ggl5rr0gf01np` | Solo Backend | | AES_KEY (IoT) | `8e3637pG7E9144E0` | Solo Backend | | Consola | juphoon.com (+34 603675786) | Julián | --- ## Naming conventions (protocolo TCP) | Tipo | Formato | Ejemplo | |---|---|---| | Watch userID | `w_` + IMEI | `w_000078932675810` | | Mobile userID | `p_` + APP account | `p_abc10086` | | Group room | `did` + `_group` | `0245423235_group` | | Single room | `did` + `_` + APP account | `0245423235_abc10086` | Nota: `@` y `.` se reemplazan por `_` en room numbers y userIDs. --- ## Documentación de referencia - Quickstart V1.1: `~/Downloads/Video call API_ Juphoon Flutter SDK quickstart V1.1.pdf` - TCP Protocol: `~/Downloads/Juphoon Video Call TCP Protocol.docx` - Connection process: `~/Downloads/video call connection process Rev2.docx` - Mutual dialing: `~/Downloads/video call mutual dialing process.docx` - Schematics: `~/Downloads/schematics _2025.03.26 (2)/` - pub.dev: https://pub.dev/packages/jc_sdk - Consola: https://developer.juphoon.com