From 1669113352e740bd953f6d692037de8662f81547 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 18 Nov 2025 09:20:46 +0100 Subject: [PATCH] Made call redirection service prototype work --- app/src/main/AndroidManifest.xml | 9 +++ .../linphone/activities/main/MainActivity.kt | 16 +++++ .../telecom/TelecomConnectionService.kt | 13 +++- .../telecom/TelecomRedirectionService.kt | 69 +++++++++++++++++++ 4 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/org/linphone/telecom/TelecomRedirectionService.kt diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c1b106232..7df1fe3ed 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -217,6 +217,15 @@ + + + + + + = android.os.Build.VERSION_CODES.Q) { + val roleManager: RoleManager = getSystemService(Context.ROLE_SERVICE) as RoleManager + // Check if the app needs to register call redirection role. + val shouldRequestRole = roleManager.isRoleAvailable(RoleManager.ROLE_CALL_REDIRECTION) && + !roleManager.isRoleHeld(RoleManager.ROLE_CALL_REDIRECTION) + if (shouldRequestRole) { + val intent = roleManager.createRequestRoleIntent(RoleManager.ROLE_CALL_REDIRECTION) + startActivityForResult(intent, 123456) + } + } + } } diff --git a/app/src/main/java/org/linphone/telecom/TelecomConnectionService.kt b/app/src/main/java/org/linphone/telecom/TelecomConnectionService.kt index fddfc8bb6..06b81ab87 100644 --- a/app/src/main/java/org/linphone/telecom/TelecomConnectionService.kt +++ b/app/src/main/java/org/linphone/telecom/TelecomConnectionService.kt @@ -104,8 +104,17 @@ class TelecomConnectionService : ConnectionService() { request: ConnectionRequest ): Connection { if (coreContext.core.callsNb == 0) { - Log.w("[Telecom Connection Service] No call in Core, aborting outgoing connection!") - return Connection.createCanceledConnection() + val uri = request.address + val address = coreContext.core.interpretUrl(uri.toString(), true) + if (address != null) { + Log.i( + "[Telecom Connection Service] Starting call to [${address.asStringUriOnly()}]" + ) + coreContext.startCall(address = address) + } else { + Log.w("[Telecom Connection Service] No call in Core, aborting outgoing connection!") + return Connection.createCanceledConnection() + } } val accountHandle = request.accountHandle diff --git a/app/src/main/java/org/linphone/telecom/TelecomRedirectionService.kt b/app/src/main/java/org/linphone/telecom/TelecomRedirectionService.kt new file mode 100644 index 000000000..43da38816 --- /dev/null +++ b/app/src/main/java/org/linphone/telecom/TelecomRedirectionService.kt @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2010-2025 Belledonne Communications SARL. + * + * This file is part of linphone-android + * (see https://www.linphone.org). + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.linphone.telecom + +import android.net.Uri +import android.os.Build +import android.telecom.CallRedirectionService +import android.telecom.PhoneAccountHandle +import androidx.annotation.RequiresApi +import androidx.core.net.toUri +import org.linphone.LinphoneApplication.Companion.coreContext +import org.linphone.core.tools.Log + +@RequiresApi(Build.VERSION_CODES.Q) +class TelecomRedirectionService : CallRedirectionService() { + companion object { + private const val TAG = "[Telecom Redirection Service]" + } + + override fun onPlaceCall( + handle: Uri, + initialPhoneAccount: PhoneAccountHandle, + allowInteractiveResponse: Boolean + ) { + Log.i("$TAG onPlaceCall called with URI [$handle]") + + if (handle.scheme != "tel") { + placeCallUnmodified() + return + } + + val number = handle.toString().substring("tel:".length) + Log.i("$TAG Extracted number [$number] from tel: URI") + + if (TelecomHelper.exists()) { + val telecomHelper = TelecomHelper.get() + val phoneAccount = telecomHelper.findExistingAccount(coreContext.context) + val handle = phoneAccount?.accountHandle + if (handle != null) { + redirectCall( + "sip:sylvain@sip.linphone.org".toUri(), + handle, + allowInteractiveResponse + ) + } else { + placeCallUnmodified() + } + } else { + placeCallUnmodified() + } + } +}