Unified call history

VoIP applications can integrate their calls into the system call log. This lets users see their VoIP call history centrally in the system dialer app and return calls directly from the dialer app. This guide describes the required changes to VoIP calling apps and system dialer apps.

Changes for the calling app

To integrate your VoIP app with the system call log, follow these steps.

Register callback intent filter

Register the system-protected intent TelecomManager.ACTION_CALL_BACK.

Once this intent filter is properly registered, any calls your app adds using CallsManager.addCall or other related Telecom APIs will be automatically logged by the system. The system uses this registered intent to later send a callback to your app when a user selects a VoIP call log entry in the dialer to return the call.

<!-- Activity to handle the callback intent from the system dialer -->
<activity
    android:name=".VoipCallActivity"
    android:exported="true">

    <!-- Register callback intent -->
    <intent-filter>
        <action android:name="android.telecom.action.CALL_BACK" />
    </intent-filter>
</activity>

Exclude call logging

Once the callback is registered, all calls are logged to the system dialer. To exclude calls on a per-call basis, set the isLogExcluded boolean to true within CallAttributesCompat.

CallAttributesCompat(
    displayName = displayName,
    address = address,
    isLogExcluded = excludeCallLogging, // to exclude call from logging
    direction = if (isIncoming) {
        CallAttributesCompat.DIRECTION_INCOMING
    } else {
        CallAttributesCompat.DIRECTION_OUTGOING
    },
    callType = CallAttributesCompat.CALL_TYPE_AUDIO_CALL,
    callCapabilities = (
        CallAttributesCompat.SUPPORTS_SET_INACTIVE
            or CallAttributesCompat.SUPPORTS_STREAM
            or CallAttributesCompat.SUPPORTS_TRANSFER
        ),
)

Handle callbacks

Calls added through CallsManager.addCall get a unique UUID through CallControlScope.getCallId.

// check the intent action for CALL_BACK
if (intent.action == TelecomManager.ACTION_CALL_BACK) {
    launchCall(
        // fetching stored call details for the UUID to initiate callback
        callDetails = getCallDetails(
            uuid = intent.getStringExtra(TelecomManager.EXTRA_UUID)
        )
    )
}

Verify call log entries

The system call log maintains a finite number of entries and eventually purges old call records. Because the app stores a mapping of UUIDs to call details for callback handling, it should periodically check which UUIDs are still present in the system call log. If a UUID is no longer in the system log, the user cannot initiate a callback for that call, and the app can safely remove the mapping from its local storage. This practice helps optimize storage.

To get the current list of UUIDs attributed to the app within the system log, use CallLog.Calls.CONTENT_VOIP_URI.

Changes for the dialer app

Follow these steps to enable the dialer app to display VoIP call logs and initiate callbacks to VoIP apps.

Display VoIP call logs in the dialer app

By default, VoIP apps call logs don't appear in the dialer app. To display the integrated call logs in the dialer app, do the following:

Initiate callbacks from dialer app

To initiate a callback from a dialer, use TelecomManager.placeCall. The platform uses the unique CallLog.Calls._ID of the call log entry to launch the correct VoIP app. This launch includes a TelecomManager.ACTION_CALL_BACK intent, which is a system-defined action for initiating a return call. This intent contains the call's UUID in intent extra TelecomManager.EXTRA_UUID, allowing the VoIP app to identify which specific call is being called back.

// Uri generated with unique ID of the call log entry to launch the respective VoIP app for callback
val address = ContentUris.withAppendedId(CallLog.Calls.CONTENT_URI, callId)

// extra information required to initiate callback
val extras = Bundle()

telecomManager.placeCall(address, extras)