Own Android call video in the foreground call service
This commit is contained in:
1 parent
04f4d29e4f
commit
a59ebcd6db
3 files changed
+25
-3
No files matched your search
@@ -82,7 +82,7 @@
|
||||
<service
|
||||
android:name=".data.CallService"
|
||||
android:exported="false"
|
||||
android:foregroundServiceType="phoneCall|microphone" />
|
||||
android:foregroundServiceType="phoneCall|microphone|camera" />
|
||||
|
||||
<service android:name=".data.StreamService" android:exported="false" android:foregroundServiceType="camera|microphone" />
|
||||
|
||||
|
||||
@@ -24,6 +24,14 @@ object CallController : TelecomCallManager.Listener {
|
||||
private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
|
||||
private val _state = MutableStateFlow<CallState?>(null)
|
||||
val state: StateFlow<CallState?> = _state
|
||||
private val _video = MutableStateFlow<CallVideoEngine?>(null)
|
||||
val video: StateFlow<CallVideoEngine?> = _video
|
||||
fun setVideo(settings: CallVideoSettings) {
|
||||
checkMain()
|
||||
val owner = service ?: return
|
||||
if (_state.value?.phase != CallPhase.ACTIVE) return
|
||||
if (owner.setVideoCapture(settings.enabled)) owner.video?.select(settings)
|
||||
}
|
||||
private val _muted = MutableStateFlow(false)
|
||||
val muted: StateFlow<Boolean> = _muted
|
||||
private val _route = MutableStateFlow(AudioRoute.SPEAKER)
|
||||
@@ -202,6 +210,7 @@ object CallController : TelecomCallManager.Listener {
|
||||
acceptSent = false
|
||||
answerWhenVisible = 0L
|
||||
owner?.shutdown()
|
||||
_video.value = null
|
||||
proximity.stop()
|
||||
TelecomCallManager.setDisconnected(id, reason)
|
||||
TelecomCallManager.removeConnection(id)
|
||||
@@ -327,6 +336,7 @@ object CallController : TelecomCallManager.Listener {
|
||||
return
|
||||
}
|
||||
accepting = false
|
||||
_video.value = owner.video
|
||||
TelecomCallManager.setActive(id)
|
||||
_state.value = st.copy(phase = CallPhase.ACTIVE, durationSeconds = 0, startedAtElapsedRealtime = SystemClock.elapsedRealtime())
|
||||
owner.audio.router.onChanged = { route, headset -> routeChanged(route, headset) }
|
||||
|
||||
@@ -43,6 +43,9 @@ class CallService : Service() {
|
||||
}
|
||||
|
||||
val audio = CallAudioEngine()
|
||||
var video: CallVideoEngine? = null
|
||||
private set
|
||||
private var cameraForeground = false
|
||||
private var callId = 0L
|
||||
private var wakeLock: PowerManager.WakeLock? = null
|
||||
private var powerEventsRegistered = false
|
||||
@@ -137,7 +140,8 @@ class CallService : Service() {
|
||||
val micType = if (microphone && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
|
||||
ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE else 0
|
||||
val types = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
ServiceInfo.FOREGROUND_SERVICE_TYPE_PHONE_CALL or micType
|
||||
ServiceInfo.FOREGROUND_SERVICE_TYPE_PHONE_CALL or micType or
|
||||
(if (cameraForeground && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA else 0)
|
||||
} else 0
|
||||
ServiceCompat.startForeground(this, NOTIFICATION_ID, notification(), types)
|
||||
LogManager.addLog("INFO", "CallService", "foreground notification id=$callId phase=${CallController.state.value?.phase}")
|
||||
@@ -149,7 +153,14 @@ class CallService : Service() {
|
||||
return false
|
||||
}
|
||||
audio.router.setPreferredRoute(ChatApplication.instance.configProvider.getCallAudioRoute())
|
||||
return audio.start(id)
|
||||
if (!audio.start(id)) return false
|
||||
video = CallVideoEngine(this, id)
|
||||
return true
|
||||
}
|
||||
|
||||
fun setVideoCapture(enabled: Boolean): Boolean {
|
||||
return try { cameraForeground = enabled; promote(true); true }
|
||||
catch (e: Exception) { cameraForeground = false; LogManager.addLog("ERROR", "call", "camera foreground failed: ${e.message}"); false }
|
||||
}
|
||||
|
||||
fun updateNotification() {
|
||||
@@ -202,6 +213,7 @@ class CallService : Service() {
|
||||
|
||||
private fun releaseResources() {
|
||||
val id = callId
|
||||
video?.stop(); video = null; cameraForeground = false
|
||||
if (powerEventsRegistered) {
|
||||
try { unregisterReceiver(powerEvents) }
|
||||
catch (e: Exception) { LogManager.addLog("WARN", "CallService", "power receiver cleanup failed id=$id: ${e.message}") }
|
||||
|
||||
Reference in new issue
Block a user