Skip to content

Conversation

@WesUnwin
Copy link
Member

@WesUnwin WesUnwin commented Oct 28, 2025

  • Lots of cleanups to make the code more manageable.
  • Switches to using a self managed phone account + self managed connections.
  • Uses a incoming call style android notification
  • Improves how connections (representing incoming/active calls) are managed to fix issues such as handling multiple incoming invites.

Must be accompanied by the "android-calls" branch of cordova-plugin-firebasex:
iotum/cordova-plugin-firebasex#8

  1. Receives a startService() intent
  • If the MyConnectionService service is for any reason not running, this intent will start it (then call onStartCommand)
  • If already running, onStartCommand is simply invoked with the intent information.
  1. MyConnectionService onStartCommand():
  • This uses the TelecomManager + PhoneAccountHandle to add a connection (representing the incoming, ringing call), tm.addNewIncomingCall(...)
  • for payload.dismiss messages, this will abort/cancel the corresponding connection
  1. onCreateIncomingConnection:
  • This is called when it is time to create a connection (sometime after tm.addNewIncomingCall()), this sets up the self-managed connection and its lifecycle methods.
  1. connection.onShowIncomingUI
  • For a self-managed connection this is called by the system when it is time to display the relevant UI (as recommended for urgent things like incoming calls, am using a call style notification).
  1. Launches a CallStyle.forIncomingCall(...) style android notification with an answer and decline button:

Works in foreground, background, lock screen and even works if the app is shutdown.

(Android decides whether to display a top card for the notification, or to launch the full screen intent/activity instead)

Full-screen intents are only sometimes launched (with restrictions), can be disabled by user, etc. would look like this (and will be shown instead of above, works on lock screen too):

  1. User clicks Decline (from card notification):
  • The CallActionReceiver responds to "rejecting" the corresponding connection, facetalk app (in MainActivity) is opened so that we can emit the "reject" event to it.

  • This is controversial - instead we could just mark the connection as disconnected, and close the notification (dont bring up facetalk web app)

  1. User clicks Answer (from card notification):
  • The CallActionReceiver receives an intent, we call connection.onAnswer, which sets the connection active, we start the process of opening the MainActivity (with the facetalk web app running in it) and emit the "answer" event to it (via CordovaCall.java CordovaPlugin function)
  • The facetalk web app responds by answering the call (when UA is registered) and handling the UI/UX of being in an active call. (bar displayed at the top of the facetalk web app).
  1. Full screen intent is launched (where supported)
  • IncomingCallActivity is displayed where user can click an anwser or decline button.

More screenshots / diagram of UI:
https://docs.google.com/drawings/d/1ccL-BhMlYNlx5qHrQSK463Je2ATh-0CGDDGvTGk2F-w/edit

Screenshot from 2025-10-30 14-14-56

…e self managed (results in onShowIncomingCallUi() now working
…le answer and decline intents from CallNotification
}
} else {
if(permissionCounter == 2) {
Intent phoneIntent = new Intent(TelecomManager.ACTION_CHANGE_PHONE_ACCOUNTS);
Copy link
Collaborator

@rex-iotum rex-iotum Oct 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be removed, I believe this is the CallingAccount permission that we no longer need for SELF_MANAGED. I would remove the CallingAccount permission from the phone and see.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are also a few permission requests in facetalk for android.permission.READ_PHONE_STATE and android.permission.READ_PHONE_NUMBERS which may not be needed anymore.


disconnectConnection(callUUID, DisconnectCause.REJECTED);

showWebApp("declineCall", payloadString); // Controversial UX but doing so that we can tell the web app to reject the call (which may let the caller not it was declined)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a way to start the app without bringing it to the front? If that's possible then it might be better UX.

Copy link
Member Author

@WesUnwin WesUnwin Nov 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll see if this works without this, there is a possibly we could directly tell the facetalk backend to decline the phone call (would have to look into whether this is practical / makes sense to do).

I'll confirm what the desired UX is, alternatively we could reject/disconnect the connection, close the notification and do nothing (which would not let the caller know its disconnected).

@rex-iotum
Copy link
Collaborator

For your sanity testing, please make sure to check all of the ringing + answer/decline scenarios of

  1. App open
  2. App open + phone locked
  3. App closed
  4. App closed + phone locked
  5. App closed + phone locked + unplugged for ~5 minutes (doze)

@rex-iotum
Copy link
Collaborator

rex-iotum commented Oct 31, 2025

I will be off for the next 2 weeks, I don't have much issue other than the old permissions needing to be removed. Plus this needing another ticket for the active call page when in the lockscreen, and verifying that it works when you toggle in/out of lockscreen when the call is active.

@rex-iotum rex-iotum requested a review from jerry2013 October 31, 2025 23:57
@rex-iotum
Copy link
Collaborator

Approved pending changes

@WesUnwin WesUnwin merged commit 49895fa into develop Nov 8, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants