Added Greate Mobile Account sub-setting to Default Phone App setting

This commit is contained in:
Juha Heinanen
2026-08-11 13:23:19 +03:00
parent 2f51e48276
commit efb3a594a3
6 changed files with 144 additions and 75 deletions

View File

@ -878,9 +878,10 @@ class BaresipService: Service() {
removeMobile = true removeMobile = true
} }
else if (Utils.pstnAccountHandle(this) == null || !isSimReady() || else if (Utils.pstnAccountHandle(this) == null || !isSimReady() ||
!telephonyManager.isVoiceCapable || (if (VERSION.SDK_INT >= 35) !telephonyManager.isDeviceVoiceCapable else !telephonyManager.isVoiceCapable) ||
SubscriptionManager.getDefaultVoiceSubscriptionId() == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { SubscriptionManager.getDefaultVoiceSubscriptionId() == SubscriptionManager.INVALID_SUBSCRIPTION_ID ||
Log.d(TAG, "Removing Mobile account (SIM not ready, not default dialer, or not voice capable)") !mobileAccount) {
Log.d(TAG, "Removing Mobile account (SIM not ready, not default dialer, not voice capable, or disabled by user)")
removeMobile = true removeMobile = true
} }
} }
@ -2110,12 +2111,11 @@ class BaresipService: Service() {
if (VERSION.SDK_INT >= 29) { if (VERSION.SDK_INT >= 29) {
if (activeCall != null) { if (activeCall != null) {
type = type or ServiceInfo.FOREGROUND_SERVICE_TYPE_PHONE_CALL 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) if (ContextCompat.checkSelfPermission(this, RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED)
type = type or ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE type = type or ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE
} }
} }
}
if (VERSION.SDK_INT >= 34) if (VERSION.SDK_INT >= 34)
type = type or ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE type = type or ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE
// Fallback for API 29-33 when no active call (specialUse not available) // Fallback for API 29-33 when no active call (specialUse not available)
@ -2325,14 +2325,17 @@ class BaresipService: Service() {
val mobileAccountHandle = Utils.pstnAccountHandle(this) val mobileAccountHandle = Utils.pstnAccountHandle(this)
val isSimReady = isSimReady() val isSimReady = isSimReady()
val isVoiceCapable = telephonyManager.isVoiceCapable val isVoiceCapable = if (VERSION.SDK_INT >= 35)
telephonyManager.isDeviceVoiceCapable
else
telephonyManager.isVoiceCapable
val voiceSubId = SubscriptionManager.getDefaultVoiceSubscriptionId() val voiceSubId = SubscriptionManager.getDefaultVoiceSubscriptionId()
val existingMobileUa = uas.value.find { it.account.isMobile || Utils.uriMatch(it.account.aor, "sip:mobile@pstn") } val existingMobileUa = uas.value.find { it.account.isMobile || Utils.uriMatch(it.account.aor, "sip:mobile@pstn") }
if (mobileAccountHandle == null || !isSimReady || !isVoiceCapable || if (mobileAccountHandle == null || !isSimReady || !isVoiceCapable ||
voiceSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { voiceSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID || !mobileAccount) {
if (existingMobileUa != null) { 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) if (existingMobileUa.uap != 0L) Api.ua_destroy(existingMobileUa.uap)
existingMobileUa.remove() existingMobileUa.remove()
if (isNativeReady) Account.saveAccounts() if (isNativeReady) Account.saveAccounts()
@ -2401,12 +2404,16 @@ class BaresipService: Service() {
private fun updateMobileStatus(newStatus: Int? = null) { private fun updateMobileStatus(newStatus: Int? = null) {
val mobileAccountHandle = Utils.pstnAccountHandle(this) val mobileAccountHandle = Utils.pstnAccountHandle(this)
val isSimReady = isSimReady() val isSimReady = isSimReady()
val isVoiceCapable = telephonyManager.isVoiceCapable val isVoiceCapable = if (VERSION.SDK_INT >= 35)
telephonyManager.isDeviceVoiceCapable
else
telephonyManager.isVoiceCapable
val voiceSubId = SubscriptionManager.getDefaultVoiceSubscriptionId() val voiceSubId = SubscriptionManager.getDefaultVoiceSubscriptionId()
val mobileUa = uas.value.find { it.account.isMobile } val mobileUa = uas.value.find { it.account.isMobile }
if (mobileUa == null || mobileAccountHandle == null || !isSimReady || !isVoiceCapable || if (mobileUa == null || mobileAccountHandle == null || !isSimReady || !isVoiceCapable ||
voiceSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { voiceSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID ||
!mobileAccount) {
addMobileUserAgent() addMobileUserAgent()
return return
} }
@ -2436,15 +2443,20 @@ class BaresipService: Service() {
if (VERSION.SDK_INT >= 29) { if (VERSION.SDK_INT >= 29) {
val isAirplaneModeOn = Utils.isAirplaneModeOn(this) val isAirplaneModeOn = Utils.isAirplaneModeOn(this)
val isSimReady = isSimReady() val isSimReady = isSimReady()
val isVoiceCapable = telephonyManager.isVoiceCapable val isVoiceCapable = if (VERSION.SDK_INT >= 35)
telephonyManager.isDeviceVoiceCapable
else
telephonyManager.isVoiceCapable
val voiceSubId = SubscriptionManager.getDefaultVoiceSubscriptionId() val voiceSubId = SubscriptionManager.getDefaultVoiceSubscriptionId()
val mobileAccountHandle = Utils.pstnAccountHandle(this) val mobileAccountHandle = Utils.pstnAccountHandle(this)
val status = if (state == ServiceState.STATE_IN_SERVICE && isSimReady && val status = if (state == ServiceState.STATE_IN_SERVICE && isSimReady &&
mobileAccountHandle != null && isVoiceCapable && mobileAccountHandle != null && isVoiceCapable &&
voiceSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) voiceSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID &&
mobileAccount)
circleGreen.getValue(colorblind) circleGreen.getValue(colorblind)
else if (mobileAccountHandle == null || isAirplaneModeOn || !isSimReady || else if (mobileAccountHandle == null || isAirplaneModeOn || !isSimReady ||
!isVoiceCapable || voiceSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) !isVoiceCapable || voiceSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID ||
!mobileAccount)
R.drawable.circle_white R.drawable.circle_white
else else
circleRed.getValue(colorblind) circleRed.getValue(colorblind)
@ -3185,6 +3197,7 @@ class BaresipService: Service() {
var instance: BaresipService? = null var instance: BaresipService? = null
var isServiceRunning = false var isServiceRunning = false
var isNativeReady = false var isNativeReady = false
var mobileAccount = true
var isStartReceived = false var isStartReceived = false
var isConfigInitialized = false var isConfigInitialized = false
var libraryLoaded = false var libraryLoaded = false

View File

@ -121,6 +121,16 @@ object Config {
if (userAgent != "") if (userAgent != "")
config = "${config}user_agent $userAgent\n" 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") val sipCuserRandom = previousVariable("sip_cuser_random")
config = if (sipCuserRandom != "") config = if (sipCuserRandom != "")
"${config}sip_cuser_random $sipCuserRandom\n" "${config}sip_cuser_random $sipCuserRandom\n"

View File

@ -957,6 +957,14 @@ private fun SettingsContent(
val defaultPhoneAppTitle = stringResource(R.string.default_phone_app) val defaultPhoneAppTitle = stringResource(R.string.default_phone_app)
val defaultPhoneAppHelp = stringResource(R.string.default_phone_app_help) val defaultPhoneAppHelp = stringResource(R.string.default_phone_app_help)
val dialerRoleNotAvailableMessage = stringResource(R.string.dialer_role_not_available) val dialerRoleNotAvailableMessage = stringResource(R.string.dialer_role_not_available)
val createMobileAccountTitle = stringResource(R.string.create_mobile_account)
val createMobileAccountHelp = stringResource(R.string.create_mobile_account_help)
val defaultDialer by viewModel.defaultDialer.collectAsState()
val mobileAccount by viewModel.mobileAccount.collectAsState()
val isSimReady = BaresipService.instance?.isSimReady() == true
Column {
Row( Row(
Modifier.fillMaxWidth().padding(end = 10.dp), Modifier.fillMaxWidth().padding(end = 10.dp),
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
@ -973,7 +981,6 @@ private fun SettingsContent(
}, },
fontSize = 18.sp fontSize = 18.sp
) )
val defaultDialer by viewModel.defaultDialer.collectAsState()
val roleManager = ctx.getSystemService(ROLE_SERVICE) as RoleManager val roleManager = ctx.getSystemService(ROLE_SERVICE) as RoleManager
val requestPermissionLauncher = rememberLauncherForActivityResult( val requestPermissionLauncher = rememberLauncherForActivityResult(
@ -993,7 +1000,10 @@ private fun SettingsContent(
val isHeld = roleManager.isRoleHeld(RoleManager.ROLE_DIALER) val isHeld = roleManager.isRoleHeld(RoleManager.ROLE_DIALER)
viewModel.defaultDialer.value = isHeld viewModel.defaultDialer.value = isHeld
if (isHeld) { if (isHeld) {
val permissions = arrayOf(Manifest.permission.READ_PHONE_STATE, Manifest.permission.READ_PHONE_NUMBERS) val permissions = arrayOf(
Manifest.permission.READ_PHONE_STATE,
Manifest.permission.READ_PHONE_NUMBERS
)
if (Utils.checkPermissions(ctx, permissions)) { if (Utils.checkPermissions(ctx, permissions)) {
BaresipService.instance?.addMobileUserAgent() BaresipService.instance?.addMobileUserAgent()
restart = true restart = true
@ -1015,19 +1025,49 @@ private fun SettingsContent(
alertMessage.value = dialerRoleNotAvailableMessage alertMessage.value = dialerRoleNotAvailableMessage
showAlert.value = true showAlert.value = true
} }
else else if (!roleManager.isRoleHeld(RoleManager.ROLE_DIALER))
if (!roleManager.isRoleHeld(RoleManager.ROLE_DIALER)) dialerRoleRequest.launch(
dialerRoleRequest.launch(roleManager.createRequestRoleIntent(RoleManager.ROLE_DIALER)) roleManager.createRequestRoleIntent(RoleManager.ROLE_DIALER)
)
} }
else else {
try { BaresipService.instance?.addMobileUserAgent()
dialerRoleRequest.launch(Intent("android.settings.MANAGE_DEFAULT_APPS_SETTINGS")) restart = true
} catch (e: ActivityNotFoundException) {
Log.e(TAG, "ActivityNotFound exception: ${e.message}")
} }
} }
) )
} }
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
}
)
}
}
}
} }
@RequiresApi(29) @RequiresApi(29)

View File

@ -30,6 +30,7 @@ class SettingsViewModel: ViewModel() {
val colorblind = MutableStateFlow(false) val colorblind = MutableStateFlow(false)
val proximitySensing = MutableStateFlow(false) val proximitySensing = MutableStateFlow(false)
val defaultDialer = MutableStateFlow(false) val defaultDialer = MutableStateFlow(false)
val mobileAccount = MutableStateFlow(true)
val defaultMessaging = MutableStateFlow(false) val defaultMessaging = MutableStateFlow(false)
val debug = MutableStateFlow(false) val debug = MutableStateFlow(false)
val sipTrace = MutableStateFlow(false) val sipTrace = MutableStateFlow(false)
@ -77,6 +78,7 @@ class SettingsViewModel: ViewModel() {
if (Build.VERSION.SDK_INT >= 29) { if (Build.VERSION.SDK_INT >= 29) {
val roleManager = ctx.getSystemService(ROLE_SERVICE) as RoleManager val roleManager = ctx.getSystemService(ROLE_SERVICE) as RoleManager
defaultDialer.value = roleManager.isRoleHeld(RoleManager.ROLE_DIALER) defaultDialer.value = roleManager.isRoleHeld(RoleManager.ROLE_DIALER)
mobileAccount.value = BaresipService.mobileAccount
defaultMessaging.value = roleManager.isRoleHeld(RoleManager.ROLE_SMS) defaultMessaging.value = roleManager.isRoleHeld(RoleManager.ROLE_SMS)
} }

View File

@ -357,6 +357,8 @@
<string name="default_phone_app">Oletus puhelusovellus</string> <string name="default_phone_app">Oletus puhelusovellus</string>
<string name="dialer_role_not_available">Oletus puhelusovellusrooli ei ole saatavana</string> <string name="dialer_role_not_available">Oletus puhelusovellusrooli ei ole saatavana</string>
<string name="default_phone_app_help">Jos merkitty, baresip on oletus puhelusovellus</string> <string name="default_phone_app_help">Jos merkitty, baresip on oletus puhelusovellus</string>
<string name="create_mobile_account">Luo Mobile-tili</string>
<string name="create_mobile_account_help">Jos merkitty, mobiilipuheluita varten luodaan virtuaalinen Mobile-tili.</string>
<string name="default_messaging_app">Oletus tekstiviestisovellus</string> <string name="default_messaging_app">Oletus tekstiviestisovellus</string>
<string name="default_messaging_app_help">Jos merkitty, baresip on tekstiviestien <string name="default_messaging_app_help">Jos merkitty, baresip on tekstiviestien
oletussovellus</string> oletussovellus</string>

View File

@ -349,6 +349,8 @@
<string name="default_phone_app">Default Phone App</string> <string name="default_phone_app">Default Phone App</string>
<string name="dialer_role_not_available">Default phone app role is not available</string> <string name="dialer_role_not_available">Default phone app role is not available</string>
<string name="default_phone_app_help">If checked, baresip is the default phone app.</string> <string name="default_phone_app_help">If checked, baresip is the default phone app.</string>
<string name="create_mobile_account">Create Mobile Account</string>
<string name="create_mobile_account_help">If checked, virtual Mobile account is created for mobile calling.</string>
<string name="default_messaging_app">Default Messaging App</string> <string name="default_messaging_app">Default Messaging App</string>
<string name="default_messaging_app_help">If checked, baresip is the default messaging app for SMS/MMS.</string> <string name="default_messaging_app_help">If checked, baresip is the default messaging app for SMS/MMS.</string>
<string name="messaging_role_not_available">Default messaging app role is not available</string> <string name="messaging_role_not_available">Default messaging app role is not available</string>