feat: add call ringing API (#6650)

this PR adds a "ringing" api that can be used for calls later.

see deltachat.h for details about the API; jsonrpc is left out until
things are settled for the needs of android/iOS

UI using this PR already successfully are
https://github.com/deltachat/deltachat-ios/pull/2638 and
https://github.com/deltachat/deltachat-android/pull/3785 ; the "payload"
passed forth and back is optimised for
https://github.com/deltachat/calls-webapp

---------

Co-authored-by: l <link2xt@testrun.org>
This commit is contained in:
bjoern
2025-08-30 23:48:38 +02:00
committed by GitHub
parent 4258088fb4
commit 0bbd910883
16 changed files with 1129 additions and 40 deletions

View File

@@ -1215,6 +1215,103 @@ void dc_set_webxdc_integration (dc_context_t* context, const char* f
uint32_t dc_init_webxdc_integration (dc_context_t* context, uint32_t chat_id);
/**
* Start an outgoing call.
* This sends a message with all relevant information to the callee,
* who will get informed by an #DC_EVENT_INCOMING_CALL event and rings.
*
* Possible actions during ringing:
*
* - caller cancels the call using dc_end_call():
* callee receives #DC_EVENT_CALL_ENDED
*
* - callee accepts using dc_accept_incoming_call():
* caller receives #DC_EVENT_OUTGOING_CALL_ACCEPTED.
* callee's devices receive #DC_EVENT_INCOMING_CALL_ACCEPTED, call starts
*
* - callee rejects using dc_end_call():
* caller receives #DC_EVENT_CALL_ENDED after 1 minute timeout.
* callee's other devices receive #DC_EVENT_CALL_ENDED
*
* - callee is already in a call:
* in this case, UI may decide to show a notification instead of ringing.
* otherwise, this is same as timeout
*
* - timeout:
* after 1 minute without action,
* caller and callee receive #DC_EVENT_CALL_ENDED
* to prevent endless ringing of callee
* in case caller got offline without being able to send cancellation message
*
* Actions during the call:
*
* - caller ends the call using dc_end_call():
* callee receives #DC_EVENT_CALL_ENDED
*
* - callee ends the call using dc_end_call():
* caller receives #DC_EVENT_CALL_ENDED
*
* Note, that the events are for updating the call screen,
* possible status messages are added and updated as usual, including the known events.
* In the UI, the sorted chatlist is used as an overview about calls as well as messages.
* To place a call with a contact that has no chat yet, use dc_create_chat_by_contact_id() first.
*
* UI will usually allow only one call at the same time,
* this has to be tracked by UI across profile, the core does not track this.
*
* @memberof dc_context_t
* @param context The context object.
* @param chat_id The chat to place a call for.
* This needs to be a one-to-one chat.
* @param place_call_info any data that other devices receive
* in #DC_EVENT_INCOMING_CALL.
* @return ID of the system message announcing the call.
*/
uint32_t dc_place_outgoing_call (dc_context_t* context, uint32_t chat_id, const char* place_call_info);
/**
* Accept incoming call.
*
* This implicitly accepts the contact request, if not yet done.
* All affected devices will receive
* either #DC_EVENT_OUTGOING_CALL_ACCEPTED or #DC_EVENT_INCOMING_CALL_ACCEPTED.
*
* @memberof dc_context_t
* @param context The context object.
* @param msg_id The ID of the call to accept.
* This is the ID reported by #DC_EVENT_INCOMING_CALL
* and equals to the ID of the corresponding info message.
* @param accept_call_info any data that other devices receive
* in #DC_EVENT_OUTGOING_CALL_ACCEPTED or #DC_EVENT_INCOMING_CALL_ACCEPTED.
* @return 1=success, 0=error
*/
int dc_accept_incoming_call (dc_context_t* context, uint32_t msg_id, const char* accept_call_info);
/**
* End incoming or outgoing call.
*
* From the view of the caller, a "cancellation",
* from the view of callee, a "rejection".
* If the call was accepted, this is a "hangup".
*
* For accepted calls,
* all participant devices get informed about the ended call via #DC_EVENT_CALL_ENDED.
* For not accepted calls, only the caller will inform the callee.
*
* If the callee rejects, the caller will get a timeout or give up at some point -
* same as for all other reasons the call cannot be established: Device not in reach, device muted, connectivity etc.
* This is to protect privacy of the callee, avoiding to check if callee is online.
*
* @memberof dc_context_t
* @param context The context object.
* @param msg_id the ID of the call.
* @return 1=success, 0=error
*/
int dc_end_call (dc_context_t* context, uint32_t msg_id);
/**
* Save a draft for a chat in the database.
*
@@ -4546,6 +4643,8 @@ int dc_msg_is_info (const dc_msg_t* msg);
* and also offer a way to fix the encryption, eg. by a button offering a QR scan
* - DC_INFO_WEBXDC_INFO_MESSAGE (32) - Info-message created by webxdc app sending `update.info`
* - DC_INFO_CHAT_E2EE (50) - Info-message for "Chat is end-to-end-encrypted"
* - DC_INFO_OUTGOING_CALL (60) - Info-message refers to an outgoing call
* - DC_INFO_INCOMING_CALL (65) - Info-message refers to an incoming call
*
* For the messages that refer to a CONTACT,
* dc_msg_get_info_contact_id() returns the contact ID.
@@ -4602,6 +4701,8 @@ uint32_t dc_msg_get_info_contact_id (const dc_msg_t* msg);
#define DC_INFO_INVALID_UNENCRYPTED_MAIL 13
#define DC_INFO_WEBXDC_INFO_MESSAGE 32
#define DC_INFO_CHAT_E2EE 50
#define DC_INFO_OUTGOING_CALL 60
#define DC_INFO_INCOMING_CALL 65
/**
@@ -6636,6 +6737,63 @@ void dc_event_unref(dc_event_t* event);
*/
#define DC_EVENT_CHANNEL_OVERFLOW 2400
/**
* Incoming call.
* UI will usually start ringing,
* or show a notification if there is already a call in some profile.
*
* Together with this event,
* an info-message is added to the corresponding chat.
* The info-message, however, is _not_ additionally notified using #DC_EVENT_INCOMING_MSG,
* if needed, this has to be done by the UI explicitly.
*
* If user takes action, dc_accept_incoming_call() or dc_end_call() should be called.
*
* Otherwise, ringing should end on #DC_EVENT_CALL_ENDED
* or #DC_EVENT_INCOMING_CALL_ACCEPTED
*
* @param data1 (int) msg_id ID of the info-message referring to the call.
* @param data2 (char*) place_call_info, text passed to dc_place_outgoing_call()
*/
#define DC_EVENT_INCOMING_CALL 2550
/**
* The callee accepted an incoming call on another device using dc_accept_incoming_call().
* The caller gets the event #DC_EVENT_OUTGOING_CALL_ACCEPTED at the same time.
*
* The event is sent unconditionally when the corresponding message is received.
* UI should only take action in case call UI was opened before, otherwise the event should be ignored.
*
* @param data1 (int) msg_id ID of the info-message referring to the call
* @param data2 (char*) accept_call_info, text passed to dc_place_outgoing_call()
*/
#define DC_EVENT_INCOMING_CALL_ACCEPTED 2560
/**
* A call placed using dc_place_outgoing_call() was accepted by the callee using dc_accept_incoming_call().
*
* The event is sent unconditionally when the corresponding message is received.
* UI should only take action in case call UI was opened before, otherwise the event should be ignored.
*
* @param data1 (int) msg_id ID of the info-message referring to the call
* @param data2 (char*) accept_call_info, text passed to dc_accept_incoming_call()
*/
#define DC_EVENT_OUTGOING_CALL_ACCEPTED 2570
/**
* An incoming or outgoing call was ended using dc_end_call().
* Moreover, the event is sent when the call was not accepted within 1 minute timeout.
*
* The event is sent unconditionally when the corresponding message is received.
* UI should only take action in case call UI was opened before, otherwise the event should be ignored.
*
* @param data1 (int) msg_id ID of the info-message referring to the call
*/
#define DC_EVENT_CALL_ENDED 2580
/**
* @}
*/