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
}
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

View File

@ -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"

View File

@ -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
}
)
}
}
}
}

View File

@ -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)
}

View File

@ -357,6 +357,8 @@
<string name="default_phone_app">Oletus puhelusovellus</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="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_help">Jos merkitty, baresip on tekstiviestien
oletussovellus</string>

View File

@ -349,6 +349,8 @@
<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="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_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>