Make sure PhoneAccount identity is valid to prevent crash in Android OS at startup

This commit is contained in:
Sylvain Berfini 2021-12-07 09:25:50 +01:00
parent d2c10ad455
commit fe9f9cbecc
8 changed files with 43 additions and 19 deletions

View file

@ -254,11 +254,11 @@ class DialerFragment : SecureFragment<DialerFragmentBinding>() {
if (corePreferences.manuallyDisabledTelecomManager) {
Log.w("[Dialer] User has manually disabled Telecom Manager feature")
} else {
if (PermissionHelper.get().hasTelecomManagerPermissions()) {
if (Compatibility.hasTelecomManagerPermissions(requireContext())) {
enableTelecomManager()
} else {
Log.i("[Dialer] Asking for Telecom Manager permissions")
Compatibility.requestTelecomManagerPermission(requireActivity(), 1)
Compatibility.requestTelecomManagerPermissions(requireActivity(), 1)
}
}
} else {

View file

@ -37,7 +37,6 @@ import org.linphone.databinding.SettingsCallFragmentBinding
import org.linphone.mediastream.Version
import org.linphone.telecom.TelecomHelper
import org.linphone.utils.Event
import org.linphone.utils.PermissionHelper
class CallSettingsFragment : GenericSettingFragment<SettingsCallFragmentBinding>() {
private lateinit var viewModel: CallSettingsViewModel
@ -93,8 +92,8 @@ class CallSettingsFragment : GenericSettingFragment<SettingsCallFragmentBinding>
viewLifecycleOwner,
{
it.consume {
if (!PermissionHelper.get().hasTelecomManagerPermissions()) {
Compatibility.requestTelecomManagerPermission(requireActivity(), 1)
if (!Compatibility.hasTelecomManagerPermissions(requireContext())) {
Compatibility.requestTelecomManagerPermissions(requireActivity(), 1)
} else if (!TelecomHelper.exists()) {
corePreferences.useTelecomManager = true
Log.w("[Telecom Helper] Doesn't exists yet, creating it")

View file

@ -151,6 +151,11 @@ class Api26Compatibility {
)
}
fun hasTelecomManagerPermission(context: Context): Boolean {
return Compatibility.hasPermission(context, Manifest.permission.READ_PHONE_STATE) &&
Compatibility.hasPermission(context, Manifest.permission.MANAGE_OWN_CALLS)
}
fun getImeFlagsForSecureChatRoom(): Int {
return EditorInfo.IME_FLAG_NO_EXTRACT_UI or EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING
}

View file

@ -50,12 +50,19 @@ class Api30Compatibility {
activity.requestPermissions(
arrayOf(
Manifest.permission.READ_PHONE_NUMBERS,
Manifest.permission.READ_PHONE_STATE,
Manifest.permission.MANAGE_OWN_CALLS
),
code
)
}
fun hasTelecomManagerPermission(context: Context): Boolean {
return Compatibility.hasPermission(context, Manifest.permission.READ_PHONE_NUMBERS) &&
Compatibility.hasPermission(context, Manifest.permission.READ_PHONE_STATE) &&
Compatibility.hasPermission(context, Manifest.permission.MANAGE_OWN_CALLS)
}
fun removeChatRoomShortcut(context: Context, chatRoom: ChatRoom) {
val shortcutManager = context.getSystemService(ShortcutManager::class.java)
val id = LinphoneUtils.getChatRoomId(chatRoom.localAddress, chatRoom.peerAddress)

View file

@ -65,7 +65,15 @@ class Compatibility {
}
// See https://developer.android.com/about/versions/11/privacy/permissions#phone-numbers
fun requestTelecomManagerPermission(activity: Activity, code: Int) {
fun hasTelecomManagerPermissions(context: Context): Boolean {
return if (Version.sdkAboveOrEqual(Version.API30_ANDROID_11)) {
Api30Compatibility.hasTelecomManagerPermission(context)
} else {
Api26Compatibility.hasTelecomManagerPermission(context)
}
}
fun requestTelecomManagerPermissions(activity: Activity, code: Int) {
if (Version.sdkAboveOrEqual(Version.API30_ANDROID_11)) {
Api30Compatibility.requestTelecomManagerPermission(activity, code)
} else {

View file

@ -312,9 +312,14 @@ class CoreContext(val context: Context, coreConfig: Config) {
// CoreContext listener must be added first!
if (Version.sdkAboveOrEqual(Version.API26_O_80) && corePreferences.useTelecomManager) {
Log.i("[Context] Creating TelecomHelper, disabling audio focus requests in AudioHelper")
core.config.setBool("audio", "android_disable_audio_focus_requests", true)
TelecomHelper.create(context)
if (Compatibility.hasTelecomManagerPermissions(context)) {
Log.i("[Context] Creating Telecom Helper, disabling audio focus requests in AudioHelper")
core.config.setBool("audio", "android_disable_audio_focus_requests", true)
TelecomHelper.create(context)
} else {
Log.w("[Context] Can't create Telecom Helper, permissions have been revoked")
corePreferences.useTelecomManager = false
}
}
if (isPush) {

View file

@ -30,6 +30,7 @@ import android.telecom.PhoneAccount
import android.telecom.PhoneAccountHandle
import android.telecom.TelecomManager
import android.telecom.TelecomManager.*
import java.lang.Exception
import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.R
import org.linphone.contact.Contact
@ -159,9 +160,16 @@ class TelecomHelper private constructor(context: Context) {
ComponentName(context, TelecomConnectionService::class.java),
context.packageName
)
val identity = coreContext.core.defaultAccount?.params?.identityAddress?.asStringUriOnly() ?: ""
// Take care that identity may be parsed, otherwise Android OS may crash during startup
// and user will have to do a factory reset...
val identity = coreContext.core.defaultAccount?.params?.identityAddress?.asStringUriOnly()
?: coreContext.core.createPrimaryContactParsed()?.asStringUriOnly()
?: "sip:linphone.android@sip.linphone.org"
val address = Uri.parse(identity)
?: throw Exception("[Telecom Helper] Identity address for phone account is null!")
val account = PhoneAccount.builder(accountHandle, context.getString(R.string.app_name))
.setAddress(Uri.parse(identity))
.setAddress(address)
.setIcon(Icon.createWithResource(context, R.drawable.linphone_logo_tinted))
.setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED)
.setHighlightColor(context.getColor(R.color.primary_color))

View file

@ -21,8 +21,6 @@ package org.linphone.utils
import android.Manifest
import android.content.Context
import android.os.Build
import androidx.annotation.RequiresApi
import org.linphone.compatibility.Compatibility
import org.linphone.core.tools.Log
@ -75,10 +73,4 @@ class PermissionHelper private constructor(private val context: Context) {
fun hasRecordAudioPermission(): Boolean {
return hasPermission(Manifest.permission.RECORD_AUDIO)
}
@RequiresApi(Build.VERSION_CODES.O)
fun hasTelecomManagerPermissions(): Boolean {
return hasPermission(Manifest.permission.READ_PHONE_NUMBERS) &&
hasPermission(Manifest.permission.MANAGE_OWN_CALLS)
}
}