diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 5bf85a42e..b096a298d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -42,6 +42,9 @@ + + + --> + + + + + + . + */ +package org.linphone.telecom + +import android.content.Context +import android.net.Uri +import android.os.Build +import android.telecom.CallRedirectionService +import android.telecom.PhoneAccount +import android.telecom.PhoneAccountHandle +import android.telecom.TelecomManager +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") + + val telecomManager: TelecomManager = coreContext.context.getSystemService(Context.TELECOM_SERVICE) as TelecomManager + val phoneAccountHandleList: List = telecomManager.selfManagedPhoneAccounts + var found = false + for (phoneAccountHandle in phoneAccountHandleList) { + val phoneAccount: PhoneAccount = + telecomManager.getPhoneAccount(phoneAccountHandle) + Log.i("$TAG handle [$phoneAccountHandle] componentName = ${phoneAccountHandle.componentName}") + if (phoneAccountHandle.componentName.packageName == coreContext.context.packageName) { + Log.i("$TAG PLACING CALL!") + redirectCall("sip:sylvain@sip.linphone.org".toUri(), phoneAccountHandle, allowInteractiveResponse) + found = true + } + } + if (!found) { + Log.i("$TAG No matching phone account handle found :'(") + placeCallUnmodified() + } + } +} diff --git a/app/src/main/java/org/linphone/ui/main/MainActivity.kt b/app/src/main/java/org/linphone/ui/main/MainActivity.kt index 56c69c961..ee8905f6c 100644 --- a/app/src/main/java/org/linphone/ui/main/MainActivity.kt +++ b/app/src/main/java/org/linphone/ui/main/MainActivity.kt @@ -22,6 +22,8 @@ package org.linphone.ui.main import android.Manifest import android.annotation.SuppressLint import android.app.Dialog +import android.app.role.RoleManager +import android.content.Context import android.content.Intent import android.content.pm.PackageManager import android.graphics.Color @@ -89,6 +91,8 @@ class MainActivity : GenericActivity() { private const val CHAT_FRAGMENT_ID = 3 private const val MEETINGS_FRAGMENT_ID = 4 + private const val REDIRECT_ROLE_REQUEST_CODE = 1 + const val ARGUMENTS_CHAT = "Chat" const val ARGUMENTS_CONVERSATION_ID = "ConversationId" } @@ -391,6 +395,8 @@ class MainActivity : GenericActivity() { Log.d("$TAG savedInstanceState is null but intent isn't, handling it") handleIntent(intent) } + + requestCallRedirectionRole() } override fun onPause() { @@ -849,4 +855,24 @@ class MainActivity : GenericActivity() { } } } + + private val requestPermissionLauncher = registerForActivityResult( + ActivityResultContracts.RequestMultiplePermissions() + ) { isGranted -> + + } + + private fun requestCallRedirectionRole() { + requestPermissionLauncher.launch(arrayOf(Manifest.permission.READ_PHONE_STATE, Manifest.permission.READ_PHONE_NUMBERS)) + if (android.os.Build.VERSION.SDK_INT >= 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, REDIRECT_ROLE_REQUEST_CODE) + } + } + } }