From efb3a594a3da460a012d4f02dac49655bb502115 Mon Sep 17 00:00:00 2001 From: Juha Heinanen Date: Tue, 11 Aug 2026 13:23:19 +0300 Subject: [PATCH] Added Greate Mobile Account sub-setting to Default Phone App setting --- .../com/tutpro/baresip/BaresipService.kt | 39 +++-- .../main/kotlin/com/tutpro/baresip/Config.kt | 10 ++ .../com/tutpro/baresip/SettingsScreen.kt | 164 +++++++++++------- .../com/tutpro/baresip/SettingsViewModel.kt | 2 + app/src/main/res/values-fi/strings.xml | 2 + app/src/main/res/values/strings.xml | 2 + 6 files changed, 144 insertions(+), 75 deletions(-) diff --git a/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt b/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt index e94342bc..1127f1c0 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt @@ -878,9 +878,10 @@ class BaresipService: Service() { removeMobile = true } else if (Utils.pstnAccountHandle(this) == null || !isSimReady() || - !telephonyManager.isVoiceCapable || - SubscriptionManager.getDefaultVoiceSubscriptionId() == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { - Log.d(TAG, "Removing Mobile account (SIM not ready, not default dialer, or not voice capable)") + (if (VERSION.SDK_INT >= 35) !telephonyManager.isDeviceVoiceCapable else !telephonyManager.isVoiceCapable) || + SubscriptionManager.getDefaultVoiceSubscriptionId() == SubscriptionManager.INVALID_SUBSCRIPTION_ID || + !mobileAccount) { + Log.d(TAG, "Removing Mobile account (SIM not ready, not default dialer, not voice capable, or disabled by user)") removeMobile = true } } @@ -2110,10 +2111,9 @@ class BaresipService: Service() { if (VERSION.SDK_INT >= 29) { if (activeCall != null) { type = type or ServiceInfo.FOREGROUND_SERVICE_TYPE_PHONE_CALL - if (VERSION.SDK_INT >= 30) { + if (VERSION.SDK_INT >= 30) if (ContextCompat.checkSelfPermission(this, RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED) type = type or ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE - } } } if (VERSION.SDK_INT >= 34) @@ -2325,14 +2325,17 @@ class BaresipService: Service() { val mobileAccountHandle = Utils.pstnAccountHandle(this) val isSimReady = isSimReady() - val isVoiceCapable = telephonyManager.isVoiceCapable + val isVoiceCapable = if (VERSION.SDK_INT >= 35) + telephonyManager.isDeviceVoiceCapable + else + telephonyManager.isVoiceCapable val voiceSubId = SubscriptionManager.getDefaultVoiceSubscriptionId() val existingMobileUa = uas.value.find { it.account.isMobile || Utils.uriMatch(it.account.aor, "sip:mobile@pstn") } if (mobileAccountHandle == null || !isSimReady || !isVoiceCapable || - voiceSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { + voiceSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID || !mobileAccount) { if (existingMobileUa != null) { - Log.d(TAG, "Removing existing Mobile account (SIM not ready, not default dialer, or not voice capable)") + Log.d(TAG, "Removing existing Mobile account (SIM not ready, not default dialer, not voice capable, or disabled by user)") if (existingMobileUa.uap != 0L) Api.ua_destroy(existingMobileUa.uap) existingMobileUa.remove() if (isNativeReady) Account.saveAccounts() @@ -2401,12 +2404,16 @@ class BaresipService: Service() { private fun updateMobileStatus(newStatus: Int? = null) { val mobileAccountHandle = Utils.pstnAccountHandle(this) val isSimReady = isSimReady() - val isVoiceCapable = telephonyManager.isVoiceCapable + val isVoiceCapable = if (VERSION.SDK_INT >= 35) + telephonyManager.isDeviceVoiceCapable + else + telephonyManager.isVoiceCapable val voiceSubId = SubscriptionManager.getDefaultVoiceSubscriptionId() val mobileUa = uas.value.find { it.account.isMobile } if (mobileUa == null || mobileAccountHandle == null || !isSimReady || !isVoiceCapable || - voiceSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { + voiceSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID || + !mobileAccount) { addMobileUserAgent() return } @@ -2436,15 +2443,20 @@ class BaresipService: Service() { if (VERSION.SDK_INT >= 29) { val isAirplaneModeOn = Utils.isAirplaneModeOn(this) val isSimReady = isSimReady() - val isVoiceCapable = telephonyManager.isVoiceCapable + val isVoiceCapable = if (VERSION.SDK_INT >= 35) + telephonyManager.isDeviceVoiceCapable + else + telephonyManager.isVoiceCapable val voiceSubId = SubscriptionManager.getDefaultVoiceSubscriptionId() val mobileAccountHandle = Utils.pstnAccountHandle(this) val status = if (state == ServiceState.STATE_IN_SERVICE && isSimReady && mobileAccountHandle != null && isVoiceCapable && - voiceSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) + voiceSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID && + mobileAccount) circleGreen.getValue(colorblind) else if (mobileAccountHandle == null || isAirplaneModeOn || !isSimReady || - !isVoiceCapable || voiceSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) + !isVoiceCapable || voiceSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID || + !mobileAccount) R.drawable.circle_white else circleRed.getValue(colorblind) @@ -3185,6 +3197,7 @@ class BaresipService: Service() { var instance: BaresipService? = null var isServiceRunning = false var isNativeReady = false + var mobileAccount = true var isStartReceived = false var isConfigInitialized = false var libraryLoaded = false diff --git a/app/src/main/kotlin/com/tutpro/baresip/Config.kt b/app/src/main/kotlin/com/tutpro/baresip/Config.kt index cdc971e7..cdfea09e 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/Config.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/Config.kt @@ -121,6 +121,16 @@ object Config { if (userAgent != "") config = "${config}user_agent $userAgent\n" + val mobileAccount = previousVariable("mobile_account") + if (mobileAccount != "") { + config = "${config}mobile_account $mobileAccount\n" + BaresipService.mobileAccount = mobileAccount != "no" + } + else { + config = "${config}mobile_account yes\n" + BaresipService.mobileAccount = true + } + val sipCuserRandom = previousVariable("sip_cuser_random") config = if (sipCuserRandom != "") "${config}sip_cuser_random $sipCuserRandom\n" diff --git a/app/src/main/kotlin/com/tutpro/baresip/SettingsScreen.kt b/app/src/main/kotlin/com/tutpro/baresip/SettingsScreen.kt index 543c5d52..a0919f22 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/SettingsScreen.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/SettingsScreen.kt @@ -957,76 +957,116 @@ private fun SettingsContent( val defaultPhoneAppTitle = stringResource(R.string.default_phone_app) val defaultPhoneAppHelp = stringResource(R.string.default_phone_app_help) val dialerRoleNotAvailableMessage = stringResource(R.string.dialer_role_not_available) - Row( - Modifier.fillMaxWidth().padding(end = 10.dp), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.Start - ) { - val ctx = LocalContext.current - Text(text = defaultPhoneAppTitle, - modifier = Modifier - .weight(1f) - .clickable { - alertTitle.value = defaultPhoneAppTitle - alertMessage.value = defaultPhoneAppHelp - showAlert.value = true - }, - fontSize = 18.sp - ) - val defaultDialer by viewModel.defaultDialer.collectAsState() - val roleManager = ctx.getSystemService(ROLE_SERVICE) as RoleManager + val createMobileAccountTitle = stringResource(R.string.create_mobile_account) + val createMobileAccountHelp = stringResource(R.string.create_mobile_account_help) - val requestPermissionLauncher = rememberLauncherForActivityResult( - ActivityResultContracts.RequestMultiplePermissions() - ) { results -> - if (results[Manifest.permission.READ_PHONE_STATE] == true) - Log.d(TAG, "READ_PHONE_STATE permission granted") - if (results[Manifest.permission.READ_PHONE_NUMBERS] == true) - Log.d(TAG, "READ_PHONE_NUMBERS permission granted") - BaresipService.instance?.addMobileUserAgent() - restart = true - } + val defaultDialer by viewModel.defaultDialer.collectAsState() + val mobileAccount by viewModel.mobileAccount.collectAsState() + val isSimReady = BaresipService.instance?.isSimReady() == true - val dialerRoleRequest = rememberLauncherForActivityResult( - contract = ActivityResultContracts.StartActivityForResult() - ) { _ -> - val isHeld = roleManager.isRoleHeld(RoleManager.ROLE_DIALER) - viewModel.defaultDialer.value = isHeld - if (isHeld) { - val permissions = arrayOf(Manifest.permission.READ_PHONE_STATE, Manifest.permission.READ_PHONE_NUMBERS) - if (Utils.checkPermissions(ctx, permissions)) { - BaresipService.instance?.addMobileUserAgent() - restart = true - } - else - requestPermissionLauncher.launch(permissions) - } - else - BaresipService.instance?.addMobileUserAgent() - restart = true - } - Switch( - checked = defaultDialer, - onCheckedChange = { - viewModel.defaultDialer.value = it - if (it) { - if (!roleManager.isRoleAvailable(RoleManager.ROLE_DIALER)) { - alertTitle.value = alertTitleText - alertMessage.value = dialerRoleNotAvailableMessage + Column { + Row( + Modifier.fillMaxWidth().padding(end = 10.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.Start + ) { + val ctx = LocalContext.current + Text(text = defaultPhoneAppTitle, + modifier = Modifier + .weight(1f) + .clickable { + alertTitle.value = defaultPhoneAppTitle + alertMessage.value = defaultPhoneAppHelp showAlert.value = true + }, + fontSize = 18.sp + ) + val roleManager = ctx.getSystemService(ROLE_SERVICE) as RoleManager + + val requestPermissionLauncher = rememberLauncherForActivityResult( + ActivityResultContracts.RequestMultiplePermissions() + ) { results -> + if (results[Manifest.permission.READ_PHONE_STATE] == true) + Log.d(TAG, "READ_PHONE_STATE permission granted") + if (results[Manifest.permission.READ_PHONE_NUMBERS] == true) + Log.d(TAG, "READ_PHONE_NUMBERS permission granted") + BaresipService.instance?.addMobileUserAgent() + restart = true + } + + val dialerRoleRequest = rememberLauncherForActivityResult( + contract = ActivityResultContracts.StartActivityForResult() + ) { _ -> + val isHeld = roleManager.isRoleHeld(RoleManager.ROLE_DIALER) + viewModel.defaultDialer.value = isHeld + if (isHeld) { + val permissions = arrayOf( + Manifest.permission.READ_PHONE_STATE, + Manifest.permission.READ_PHONE_NUMBERS + ) + if (Utils.checkPermissions(ctx, permissions)) { + BaresipService.instance?.addMobileUserAgent() + restart = true } else - if (!roleManager.isRoleHeld(RoleManager.ROLE_DIALER)) - dialerRoleRequest.launch(roleManager.createRequestRoleIntent(RoleManager.ROLE_DIALER)) + requestPermissionLauncher.launch(permissions) } else - try { - dialerRoleRequest.launch(Intent("android.settings.MANAGE_DEFAULT_APPS_SETTINGS")) - } catch (e: ActivityNotFoundException) { - Log.e(TAG, "ActivityNotFound exception: ${e.message}") - } + BaresipService.instance?.addMobileUserAgent() + restart = true } - ) + Switch( + checked = defaultDialer, + onCheckedChange = { + viewModel.defaultDialer.value = it + if (it) { + if (!roleManager.isRoleAvailable(RoleManager.ROLE_DIALER)) { + alertTitle.value = alertTitleText + alertMessage.value = dialerRoleNotAvailableMessage + showAlert.value = true + } + else if (!roleManager.isRoleHeld(RoleManager.ROLE_DIALER)) + dialerRoleRequest.launch( + roleManager.createRequestRoleIntent(RoleManager.ROLE_DIALER) + ) + } + else { + BaresipService.instance?.addMobileUserAgent() + restart = true + } + } + ) + } + + if (defaultDialer && isSimReady) { + Row( + Modifier.fillMaxWidth().padding(start = 16.dp, end = 10.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.Start + ) { + Text(text = createMobileAccountTitle, + modifier = Modifier + .weight(1f) + .clickable { + alertTitle.value = createMobileAccountTitle + alertMessage.value = createMobileAccountHelp + showAlert.value = true + }, + fontSize = 18.sp + ) + Switch( + checked = mobileAccount, + onCheckedChange = { + viewModel.mobileAccount.value = it + BaresipService.mobileAccount = it + Config.replaceVariable("mobile_account", if (it) "yes" else "no") + Config.save() + BaresipService.instance?.addMobileUserAgent() + restart = true + } + ) + } + } } } diff --git a/app/src/main/kotlin/com/tutpro/baresip/SettingsViewModel.kt b/app/src/main/kotlin/com/tutpro/baresip/SettingsViewModel.kt index a101c02e..6272b76d 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/SettingsViewModel.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/SettingsViewModel.kt @@ -30,6 +30,7 @@ class SettingsViewModel: ViewModel() { val colorblind = MutableStateFlow(false) val proximitySensing = MutableStateFlow(false) val defaultDialer = MutableStateFlow(false) + val mobileAccount = MutableStateFlow(true) val defaultMessaging = MutableStateFlow(false) val debug = MutableStateFlow(false) val sipTrace = MutableStateFlow(false) @@ -77,6 +78,7 @@ class SettingsViewModel: ViewModel() { if (Build.VERSION.SDK_INT >= 29) { val roleManager = ctx.getSystemService(ROLE_SERVICE) as RoleManager defaultDialer.value = roleManager.isRoleHeld(RoleManager.ROLE_DIALER) + mobileAccount.value = BaresipService.mobileAccount defaultMessaging.value = roleManager.isRoleHeld(RoleManager.ROLE_SMS) } diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index e5a9ac58..110aefa2 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -357,6 +357,8 @@ Oletus puhelusovellus Oletus puhelusovellusrooli ei ole saatavana Jos merkitty, baresip on oletus puhelusovellus + Luo Mobile-tili + Jos merkitty, mobiilipuheluita varten luodaan virtuaalinen Mobile-tili. Oletus tekstiviestisovellus Jos merkitty, baresip on tekstiviestien oletussovellus diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5e98a204..ba997d7c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -349,6 +349,8 @@ Default Phone App Default phone app role is not available If checked, baresip is the default phone app. + Create Mobile Account + If checked, virtual Mobile account is created for mobile calling. Default Messaging App If checked, baresip is the default messaging app for SMS/MMS. Default messaging app role is not available