Make a call that goes nowhere say so
Android's Session.sendCallSignal called the send path and threw the result away. That result is the same Sent every other send returns - how many devices took it, which failed - so an offer that reached NOBODY was indistinguishable from one that rang. The caller watched "Calling..." for a signal that had gone nowhere, and neither device had anything to say so. The same shape as the message-loss bug fixed earlier today, on the one path where the UI never shows a delivery banner because a call is placed from inside a WebRTC callback. Also instruments the drops. An incoming offer can be discarded in five places in iOS's CallManager - already-ended, older than the dial timeout, busy, wrong state, unknown id - and every one was a bare `return`. Working out which of the five happened costs more than the logging does. Same treatment E2EInbox.dropped already gives ingest, and for the same reason. Not a fix for "Android calls iOS and nothing happens" - I have not reproduced that. It rules out and instruments: the wire shapes match, iOS builds its CallManager eagerly at sign-in so onCallSignal is always hooked, Android sets no from_addr so the federated fork is not swallowing it, and every clock (mac, host, relay, db) agrees within a second so the staleness check is not misfiring. The next attempt will say where it stopped instead of nothing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
780dc50652
commit
b74cc1907f
@@ -182,6 +182,8 @@ class CallManager(
|
||||
private var pendingOffer: Pair<Long, Content.CallSignal>? = null
|
||||
|
||||
fun onSignal(fromUser: Long, incoming: Content.CallSignal, turn: JSONObject?) {
|
||||
android.util.Log.i("fnmsg-call",
|
||||
"call signal in: ${incoming.action} from $fromUser state=$state")
|
||||
when (incoming.action) {
|
||||
Content.CallSignal.OFFER -> {
|
||||
// ⚠️ One call at a time. A second offer while busy is declined
|
||||
|
||||
@@ -1026,6 +1026,14 @@ class MessengerViewModel(app: Application) : AndroidViewModel(app) {
|
||||
val current = session ?: return@launch
|
||||
val manager = callManager()
|
||||
val turn = withContext(Dispatchers.IO) { current.turnCredentials() }
|
||||
// 🔴 **Whether the offer left, and to how many devices.** "I called
|
||||
// them and nothing happened on the other phone" had no evidence on
|
||||
// either side: the send path reports partial delivery to the UI as a
|
||||
// banner, but a call places its offer from inside the WebRTC callback
|
||||
// and that banner is never shown. A call to somebody with no registered
|
||||
// device looked identical to a call that rang.
|
||||
android.util.Log.i("fnmsg-call",
|
||||
"placing call to $peerId, turn=${if (turn == null) "none" else "yes"}")
|
||||
update {
|
||||
it.copy(call = Phase.CallState(
|
||||
state = CallManager.State.DIALLING,
|
||||
|
||||
@@ -397,9 +397,30 @@ class Session(
|
||||
* what you typed in it is not acceptable. The delivery counts still tell
|
||||
* the caller what happened.
|
||||
*/
|
||||
/** Send one call signal to a peer. */
|
||||
fun sendCallSignal(peerUserId: Long, signal: io.flamenet.e2e.Content.CallSignal) {
|
||||
conversations.sendCallSignal(peerUserId, signal)
|
||||
/**
|
||||
* Send one call signal to a peer.
|
||||
*
|
||||
* 🔴 **The result used to be discarded.** `sendCallSignal` returns the same
|
||||
* `Sent` every other send does — how many devices took it, and which
|
||||
* failed — and this threw it away. So an offer that reached NOBODY (the
|
||||
* peer signed out, no registered device, a session that would not open)
|
||||
* was indistinguishable from one that rang: the caller sat watching
|
||||
* "Calling…" for a signal that had gone nowhere, and there was nothing on
|
||||
* either device to say so. Exactly the shape of the message-loss bug on the
|
||||
* text path, on the one path where the UI never shows a delivery banner.
|
||||
*
|
||||
* Returns it now, and logs the zero case, because a call is placed from
|
||||
* inside a WebRTC callback where there is nowhere to put a banner.
|
||||
*/
|
||||
fun sendCallSignal(peerUserId: Long, signal: io.flamenet.e2e.Content.CallSignal):
|
||||
Conversations.Sent {
|
||||
val sent = conversations.sendCallSignal(peerUserId, signal)
|
||||
if (!sent.reachedSomeone) {
|
||||
android.util.Log.w("fnmsg-call",
|
||||
"call signal ${signal.action} to $peerUserId reached NO devices: " +
|
||||
sent.failed.entries.joinToString { "${it.key}=${it.value}" })
|
||||
}
|
||||
return sent
|
||||
}
|
||||
|
||||
/** TURN credentials, or null when this relay has none configured. */
|
||||
|
||||
Reference in New Issue
Block a user