Skip to content

Commit

Permalink
fix regression in normal call handling
Browse files Browse the repository at this point in the history
  • Loading branch information
crc-32 committed Aug 1, 2024
1 parent 6fc3480 commit 86a714e
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ import kotlinx.coroutines.launch
import javax.inject.Inject
import kotlin.random.Random
import io.rebble.cobble.bluetooth.ConnectionLooper
import javax.inject.Singleton

@Singleton
class CallNotificationProcessor @Inject constructor(
exceptionHandler: GlobalExceptionHandler,
private val prefs: KMPPrefs,
Expand Down Expand Up @@ -73,53 +75,6 @@ class CallNotificationProcessor @Inject constructor(
previousState = state
}.launchIn(coroutineScope)

phoneControl.receivedMessages.receiveAsFlow().onEach {
if (connectionLooper.connectionState.value !is ConnectionState.Connected) {
Logging.w("Ignoring phone control message because watch is not connected")
return@onEach
}
when (it) {
is PhoneControl.Answer -> {
synchronized(this@CallNotificationProcessor) {
val state = callState.value as? CallState.RINGING ?: return@onEach
if (it.cookie.get() == state.cookie) {
Logging.d("Answering call")
state.notification.answer?.send() ?: run {
callState.value = CallState.IDLE
return@synchronized
}
callState.value = CallState.ONGOING(state.notification, state.cookie)
}
}
}

is PhoneControl.Hangup -> {
synchronized(this@CallNotificationProcessor) {
when (val state = callState.value) {
is CallState.RINGING -> {
if (it.cookie.get() == state.cookie) {
Logging.d("Rejecting ringing call")
state.notification.decline?.send()
callState.value = CallState.IDLE
}
}
is CallState.ONGOING -> {
if (it.cookie.get() == state.cookie) {
Logging.d("Disconnecting call")
state.notification.hangUp?.send()
callState.value = CallState.IDLE
}
}
}
}
}

else -> {
Logging.w("Unhandled phone control message: $it")
}
}
}.launchIn(coroutineScope)

}

companion object {
Expand All @@ -130,6 +85,9 @@ class CallNotificationProcessor @Inject constructor(
}

fun processCallNotification(sbn: StatusBarNotification) {
if (sbn.packageName == "com.google.android.dialer" || sbn.packageName == "com.android.server.telecom") {
return // Ignore system call notifications, we handle those with InCallService
}
val interpreter = callPackages[sbn.packageName] ?: run {
Logging.d("Call notification from ${sbn.packageName} does not have an interpreter")
return
Expand Down Expand Up @@ -185,4 +143,51 @@ class CallNotificationProcessor @Inject constructor(
}
}
}

fun handleCallAction(action: PhoneControl) {
if (connectionLooper.connectionState.value !is ConnectionState.Connected) {
Logging.w("Ignoring phone control message because watch is not connected")
return
}
when (action) {
is PhoneControl.Answer -> {
synchronized(this@CallNotificationProcessor) {
val state = callState.value as? CallState.RINGING ?: return
if (action.cookie.get() == state.cookie) {
Logging.d("Answering call")
state.notification.answer?.send() ?: run {
callState.value = CallState.IDLE
return@synchronized
}
callState.value = CallState.ONGOING(state.notification, state.cookie)
}
}
}

is PhoneControl.Hangup -> {
synchronized(this@CallNotificationProcessor) {
when (val state = callState.value) {
is CallState.RINGING -> {
if (action.cookie.get() == state.cookie) {
Logging.d("Rejecting ringing call")
state.notification.decline?.send()
callState.value = CallState.IDLE
}
}
is CallState.ONGOING -> {
if (action.cookie.get() == state.cookie) {
Logging.d("Disconnecting call")
state.notification.hangUp?.send()
callState.value = CallState.IDLE
}
}
}
}
}

else -> {
Logging.w("Unhandled phone control message: $action")
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import android.telecom.InCallService
import android.telecom.VideoProfile
import io.rebble.cobble.CobbleApplication
import io.rebble.cobble.bluetooth.ConnectionLooper
import io.rebble.cobble.notifications.CallNotificationProcessor
import io.rebble.cobble.shared.domain.state.ConnectionState
import io.rebble.libpebblecommon.packets.PhoneControl
import io.rebble.libpebblecommon.services.PhoneControlService
Expand All @@ -24,6 +25,7 @@ class InCallService : InCallService() {
private lateinit var phoneControlService: PhoneControlService
private lateinit var connectionLooper: ConnectionLooper
private lateinit var contentResolver: ContentResolver
private lateinit var callNotificationProcessor: CallNotificationProcessor

private var lastCookie: UInt? = null
private var lastCall: Call? = null
Expand All @@ -37,6 +39,7 @@ class InCallService : InCallService() {
coroutineScope = CoroutineScope(
SupervisorJob() + injectionComponent.createExceptionHandler()
)
callNotificationProcessor = injectionComponent.createCallNotificationProcessor()
contentResolver = applicationContext.contentResolver
listenForPhoneControlMessages()
}
Expand All @@ -52,6 +55,8 @@ class InCallService : InCallService() {
synchronized(this@InCallService) {
if (it.cookie.get() == lastCookie) {
lastCall?.answer(VideoProfile.STATE_AUDIO_ONLY) // Answering from watch probably means a headset or something
} else {
callNotificationProcessor.handleCallAction(it)
}
}
}
Expand All @@ -69,6 +74,8 @@ class InCallService : InCallService() {
call.disconnect()
}
}
} else {
callNotificationProcessor.handleCallAction(it)
}
}
}
Expand Down

0 comments on commit 86a714e

Please sign in to comment.