From 38b5bef715417b76b665898b095368b8c109d2a7 Mon Sep 17 00:00:00 2001 From: Juha Heinanen Date: Thu, 25 Dec 2025 11:25:12 +0200 Subject: [PATCH] Added Check Origin account setting Get Settings and Account strings outside of composables --- app/src/main/assets/config.static | 1 + app/src/main/cpp/baresip.c | 16 + .../main/kotlin/com/tutpro/baresip/Account.kt | 3 + .../com/tutpro/baresip/AccountScreen.kt | 318 +++++++++++------ .../com/tutpro/baresip/AccountViewModel.kt | 2 + .../com/tutpro/baresip/AccountsScreen.kt | 18 +- app/src/main/kotlin/com/tutpro/baresip/Api.kt | 2 + .../com/tutpro/baresip/SettingsScreen.kt | 329 ++++++++++-------- app/src/main/res/values-fi/strings.xml | 9 +- app/src/main/res/values/strings.xml | 7 +- 10 files changed, 438 insertions(+), 267 deletions(-) diff --git a/app/src/main/assets/config.static b/app/src/main/assets/config.static index 6ca4c9f7..476d4e8a 100644 --- a/app/src/main/assets/config.static +++ b/app/src/main/assets/config.static @@ -2,6 +2,7 @@ poll_method epoll call_local_timeout 120 call_max_calls 4 call_hold_other_calls yes +filter_registrar udp,tcp,tls,ws,wss audio_player aaudio,nil audio_source aaudio,nil audio_alert aaudio,nil diff --git a/app/src/main/cpp/baresip.c b/app/src/main/cpp/baresip.c index 82c5edf3..9ce8339e 100644 --- a/app/src/main/cpp/baresip.c +++ b/app/src/main/cpp/baresip.c @@ -827,6 +827,22 @@ JNIEXPORT jint JNICALL Java_com_tutpro_baresip_Api_account_1set_1regint( return account_set_regint((struct account *)acc, regint); } +JNIEXPORT jboolean JNICALL Java_com_tutpro_baresip_Api_account_1check_1origin( + JNIEnv *env, jobject obj, jlong acc) +{ + (void)env; + (void)obj; + return account_check_origin((struct account *)acc); +} + +JNIEXPORT void JNICALL Java_com_tutpro_baresip_Api_account_1set_1check_1origin( + JNIEnv *env, jobject obj, jlong acc, jboolean value) +{ + (void)env; + (void)obj; + account_set_check_origin((struct account *)acc, value); +} + JNIEXPORT jstring JNICALL Java_com_tutpro_baresip_Api_account_1mediaenc( JNIEnv *env, jobject obj, jlong acc) { diff --git a/app/src/main/kotlin/com/tutpro/baresip/Account.kt b/app/src/main/kotlin/com/tutpro/baresip/Account.kt index 105ded9d..845a7b70 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/Account.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/Account.kt @@ -21,6 +21,7 @@ class Account(val accp: Long) { var audioCodec = ArrayList() var videoCodec = ArrayList() var regint = Api.account_regint(accp) + var checkOrigin = true var configuredRegInt = REGISTRATION_INTERVAL var mediaEnc = Api.account_mediaenc(accp) var rtcpMux = Api.account_rtcp_mux(accp) @@ -101,6 +102,8 @@ class Account(val accp: Long) { res = "$res;sipnat=outbound" } + if (!checkOrigin) res += ";check_origin=no" + if (mediaNat != "") res += ";medianat=${mediaNat}" if (stunServer != "") diff --git a/app/src/main/kotlin/com/tutpro/baresip/AccountScreen.kt b/app/src/main/kotlin/com/tutpro/baresip/AccountScreen.kt index 52c3fee4..0a876ff5 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/AccountScreen.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/AccountScreen.kt @@ -218,7 +218,6 @@ private fun AccountContent( ) { val ctx = LocalContext.current val aor = ua.account.aor - val luri = ua.account.luri val mediaNat by viewModel.mediaNat.collectAsState() val showStun by remember { derivedStateOf { mediaNat.isNotEmpty() } } @@ -233,7 +232,7 @@ private fun AccountContent( horizontalArrangement = Arrangement.Start ) { OutlinedTextField( - value = luri, + value = ua.account.luri, enabled = false, onValueChange = {}, modifier = Modifier.fillMaxWidth(), @@ -254,6 +253,8 @@ private fun AccountContent( @Composable fun Nickname() { + val nickNameTitle = stringResource(R.string.nickname) + val nickNameHelp = stringResource(R.string.account_nickname_help) Row( Modifier.fillMaxWidth().padding(top = 8.dp, end = 10.dp), verticalAlignment = Alignment.CenterVertically, @@ -262,18 +263,18 @@ private fun AccountContent( val nickName by viewModel.nickName.collectAsState() OutlinedTextField( value = nickName, - placeholder = { Text(stringResource(R.string.nickname)) }, + placeholder = { Text(nickNameTitle) }, onValueChange = { viewModel.nickName.value = it }, modifier = Modifier .fillMaxWidth() .clickable { - alertTitle.value = ctx.getString(R.string.nickname) - alertMessage.value = ctx.getString(R.string.account_nickname_help) + alertTitle.value = nickNameTitle + alertMessage.value = nickNameHelp showAlert.value = true }, singleLine = true, textStyle = TextStyle(fontSize = 18.sp), - label = { Text(stringResource(R.string.nickname)) }, + label = { Text(nickNameTitle) }, keyboardOptions = KeyboardOptions( capitalization = KeyboardCapitalization.Words, keyboardType = KeyboardType.Text), @@ -283,7 +284,8 @@ private fun AccountContent( @Composable fun DisplayName() { - val ctx = LocalContext.current + val displayNameTitle = stringResource(R.string.display_name) + val displayNameHelp = stringResource(R.string.display_name_help) Row( Modifier.fillMaxWidth().padding(top = 8.dp, end = 10.dp), verticalAlignment = Alignment.CenterVertically, @@ -292,18 +294,18 @@ private fun AccountContent( val displayName by viewModel.displayName.collectAsState() OutlinedTextField( value = displayName, - placeholder = { Text(stringResource(R.string.display_name)) }, + placeholder = { Text(displayNameTitle) }, onValueChange = { viewModel.displayName.value = it }, modifier = Modifier .fillMaxWidth() .clickable { - alertTitle.value = ctx.getString(R.string.display_name) - alertMessage.value = ctx.getString(R.string.display_name_help) + alertTitle.value = displayNameTitle + alertMessage.value = displayNameHelp showAlert.value = true }, singleLine = true, textStyle = TextStyle(fontSize = 18.sp), - label = { Text(stringResource(R.string.display_name)) }, + label = { Text(displayNameTitle) }, keyboardOptions = KeyboardOptions( capitalization = KeyboardCapitalization.Sentences, keyboardType = KeyboardType.Text @@ -314,7 +316,8 @@ private fun AccountContent( @Composable fun AuthUser() { - val ctx = LocalContext.current + val authenticationUserNameTitle = stringResource(R.string.authentication_username) + val authenticationUserNameHelp = stringResource(R.string.authentication_username_help) Row( Modifier.fillMaxWidth().padding(top = 8.dp, end = 10.dp), verticalAlignment = Alignment.CenterVertically, @@ -323,17 +326,17 @@ private fun AccountContent( val authUser by viewModel.authUser.collectAsState() OutlinedTextField( value = authUser, - placeholder = { Text(stringResource(R.string.authentication_username)) }, + placeholder = { Text(authenticationUserNameTitle) }, onValueChange = { viewModel.authUser.value = it }, modifier = Modifier .fillMaxWidth() .clickable { - alertTitle.value = ctx.getString(R.string.authentication_username) - alertMessage.value = ctx.getString(R.string.authentication_username_help) + alertTitle.value = authenticationUserNameTitle + alertMessage.value = authenticationUserNameHelp showAlert.value = true }, textStyle = TextStyle(fontSize = 18.sp), - label = { Text(stringResource(R.string.authentication_username)) }, + label = { Text(authenticationUserNameTitle) }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text) ) } @@ -341,7 +344,8 @@ private fun AccountContent( @Composable fun AuthPass() { - val ctx = LocalContext.current + val authenticationPasswordTitle = stringResource(R.string.authentication_password) + val authenticationPasswordHelp = stringResource(R.string.authentication_password_help) val showPassword = remember { mutableStateOf(false) } Row( Modifier.fillMaxWidth().padding(top = 8.dp, end = 10.dp), @@ -351,7 +355,7 @@ private fun AccountContent( val authPass by viewModel.authPass.collectAsState() OutlinedTextField( value = authPass, - placeholder = { Text(stringResource(R.string.authentication_password)) }, + placeholder = { Text(authenticationPasswordTitle) }, onValueChange = { viewModel.authPass.value = it }, singleLine = true, visualTransformation = if (showPassword.value) @@ -375,12 +379,12 @@ private fun AccountContent( modifier = Modifier .fillMaxWidth() .clickable { - alertTitle.value = ctx.getString(R.string.authentication_password) - alertMessage.value = ctx.getString(R.string.authentication_password_help) + alertTitle.value = authenticationPasswordTitle + alertMessage.value = authenticationPasswordHelp showAlert.value = true }, textStyle = TextStyle(fontSize = 18.sp), - label = { Text(stringResource(R.string.authentication_password)) }, + label = { Text(authenticationPasswordTitle) }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text) ) } @@ -412,14 +416,15 @@ private fun AccountContent( @Composable fun Outbound() { - val ctx = LocalContext.current + val outboundProxiesTitle = stringResource(R.string.outbound_proxies) + val outboundProxiesHelp = stringResource(R.string.outbound_proxies_help) Text(text = stringResource(R.string.outbound_proxies), fontSize = 18.sp, modifier = Modifier .padding(top = 8.dp) .clickable { - alertTitle.value = ctx.getString(R.string.outbound_proxies) - alertMessage.value = ctx.getString(R.string.outbound_proxies_help) + alertTitle.value = outboundProxiesTitle + alertMessage.value = outboundProxiesHelp showAlert.value = true } ) @@ -429,14 +434,15 @@ private fun AccountContent( horizontalArrangement = Arrangement.Start ) { val outbound1 by viewModel.outbound1.collectAsState() + val sipUriOfProxyServerTitle = stringResource(R.string.sip_uri_of_proxy_server) OutlinedTextField( value = outbound1, - placeholder = { Text(stringResource(R.string.sip_uri_of_proxy_server)) }, + placeholder = { Text(sipUriOfProxyServerTitle) }, onValueChange = { viewModel.outbound1.value = it }, modifier = Modifier.fillMaxWidth(), singleLine = true, textStyle = TextStyle(fontSize = 18.sp), - label = { Text(stringResource(R.string.sip_uri_of_proxy_server)) }, + label = { Text(sipUriOfProxyServerTitle) }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text) ) } @@ -446,14 +452,15 @@ private fun AccountContent( horizontalArrangement = Arrangement.Start ) { val outbound2 by viewModel.outbound2.collectAsState() + val anotherProxyServerTitle = stringResource(R.string.sip_uri_of_another_proxy_server) OutlinedTextField( value = outbound2, - placeholder = { Text(stringResource(R.string.sip_uri_of_another_proxy_server)) }, + placeholder = { Text(anotherProxyServerTitle) }, onValueChange = { viewModel.outbound2.value = it }, modifier = Modifier.fillMaxWidth(), singleLine = true, textStyle = TextStyle(fontSize = 18.sp), - label = { Text(stringResource(R.string.sip_uri_of_another_proxy_server)) }, + label = { Text(anotherProxyServerTitle) }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text) ) } @@ -461,18 +468,19 @@ private fun AccountContent( @Composable fun Register() { - val ctx = LocalContext.current + val registerTitle = stringResource(R.string.register) + val registerHelp = stringResource(R.string.register_help) Row( Modifier.fillMaxWidth().padding(end = 10.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Start ) { - Text(text = stringResource(R.string.register), + Text(text = registerTitle, modifier = Modifier .weight(1f) .clickable { - alertTitle.value = ctx.getString(R.string.register) - alertMessage.value = ctx.getString(R.string.register_help) + alertTitle.value = registerTitle + alertMessage.value = registerHelp showAlert.value = true }, fontSize = 18.sp, @@ -487,7 +495,8 @@ private fun AccountContent( @Composable fun RegInt() { - val ctx = LocalContext.current + val regIntTitle = stringResource(R.string.reg_int) + val regIntHelp = stringResource(R.string.reg_int_help) Row( Modifier.fillMaxWidth().padding(end = 10.dp), verticalAlignment = Alignment.CenterVertically, @@ -496,23 +505,50 @@ private fun AccountContent( val regInt by viewModel.regInt.collectAsState() OutlinedTextField( value = regInt, - placeholder = { Text(stringResource(R.string.reg_int)) }, + placeholder = { Text(regIntTitle) }, onValueChange = { viewModel.regInt.value = it }, modifier = Modifier .fillMaxWidth() .clickable { - alertTitle.value = ctx.getString(R.string.reg_int) - alertMessage.value = ctx.getString(R.string.reg_int_help) + alertTitle.value = regIntTitle + alertMessage.value = regIntHelp showAlert.value = true }, singleLine = true, textStyle = TextStyle(fontSize = 18.sp), - label = { Text(stringResource(R.string.reg_int)) }, + label = { Text(regIntTitle) }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number) ) } } + @Composable + fun CheckOrigin() { + val checkOriginTitle = stringResource(R.string.check_origin) + val checkOriginHelp = stringResource(R.string.check_origin_help) + Row( + Modifier.fillMaxWidth().padding(end = 10.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.Start + ) { + Text(text = checkOriginTitle, + modifier = Modifier + .weight(1f) + .clickable { + alertTitle.value = checkOriginTitle + alertMessage.value = checkOriginHelp + showAlert.value = true + }, + fontSize = 18.sp, + ) + val checkOrigin by viewModel.checkOrigin.collectAsState() + Switch( + checked = checkOrigin, + onCheckedChange = { viewModel.checkOrigin.value = it } + ) + } + } + @Composable fun AudioCodecs(navController: NavController, aor: String) { Row( @@ -538,18 +574,19 @@ private fun AccountContent( @Composable fun MediaEnc() { - val ctx = LocalContext.current + val mediaEncryptionTitle = stringResource(R.string.media_encryption) + val mediaEncryptionHelp = stringResource(R.string.media_encryption_help) Row( Modifier.fillMaxWidth().padding(end = 10.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Start ) { - Text(text = stringResource(R.string.media_encryption), + Text(text = mediaEncryptionTitle, modifier = Modifier .weight(1f) .clickable { - alertTitle.value = ctx.getString(R.string.media_encryption) - alertMessage.value = ctx.getString(R.string.media_encryption_help) + alertTitle.value = mediaEncryptionTitle + alertMessage.value = mediaEncryptionHelp showAlert.value = true }, fontSize = 18.sp @@ -595,18 +632,19 @@ private fun AccountContent( @Composable fun MediaNat() { - val ctx = LocalContext.current + val mediaNatTitle = stringResource(R.string.media_nat) + val mediaNatHelp = stringResource(R.string.media_nat_help) Row( Modifier.fillMaxWidth().padding(end = 10.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Start ) { - Text(text = stringResource(R.string.media_nat), + Text(mediaNatTitle, modifier = Modifier .weight(1f) .clickable { - alertTitle.value = ctx.getString(R.string.media_nat) - alertMessage.value = ctx.getString(R.string.media_nat_help) + alertTitle.value = mediaNatTitle + alertMessage.value = mediaNatHelp showAlert.value = true }, fontSize = 18.sp @@ -653,6 +691,8 @@ private fun AccountContent( @Composable fun StunServer() { + val stunServerTitle = stringResource(R.string.stun_server) + val stunServerHelp = stringResource(R.string.stun_server_help) Row( Modifier.fillMaxWidth().padding(end = 10.dp), verticalAlignment = Alignment.CenterVertically, @@ -661,17 +701,17 @@ private fun AccountContent( val stunServer by viewModel.stunServer.collectAsState() OutlinedTextField( value = stunServer, - placeholder = { Text(stringResource(R.string.stun_server)) }, + placeholder = { Text(stunServerTitle) }, onValueChange = { viewModel.stunServer.value = it }, modifier = Modifier .fillMaxWidth() .clickable { - alertTitle.value = ctx.getString(R.string.stun_server) - alertMessage.value = ctx.getString(R.string.stun_server_help) + alertTitle.value = stunServerTitle + alertMessage.value = stunServerHelp showAlert.value = true }, textStyle = TextStyle(fontSize = 18.sp), - label = { Text(stringResource(R.string.stun_server)) }, + label = { Text(stunServerTitle) }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text) ) } @@ -679,6 +719,8 @@ private fun AccountContent( @Composable fun StunUser() { + val stunUsernameTitle = stringResource(R.string.stun_username) + val stunUsernameHelp = stringResource(R.string.stun_username_help) Row( Modifier.fillMaxWidth().padding(top = 8.dp, end = 10.dp), verticalAlignment = Alignment.CenterVertically, @@ -687,17 +729,17 @@ private fun AccountContent( val stunUser by viewModel.stunUser.collectAsState() OutlinedTextField( value = stunUser, - placeholder = { Text(stringResource(R.string.stun_username)) }, + placeholder = { Text(stunUsernameTitle) }, onValueChange = { viewModel.stunUser.value = it }, modifier = Modifier .fillMaxWidth() .clickable { - alertTitle.value = ctx.getString(R.string.stun_username) - alertMessage.value = ctx.getString(R.string.stun_username_help) + alertTitle.value = stunUsernameTitle + alertMessage.value = stunUsernameHelp showAlert.value = true }, textStyle = TextStyle(fontSize = 18.sp), - label = { Text(stringResource(R.string.stun_username)) }, + label = { Text(stunUsernameTitle) }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text) ) } @@ -705,6 +747,8 @@ private fun AccountContent( @Composable fun StunPass() { + val stunPasswordTitle = stringResource(R.string.stun_password) + val stunPasswordHelp = stringResource(R.string.stun_password_help) val showPassword = remember { mutableStateOf(false) } Row( Modifier.fillMaxWidth().padding(end = 10.dp), @@ -714,7 +758,7 @@ private fun AccountContent( val stunPass by viewModel.stunPass.collectAsState() OutlinedTextField( value = stunPass, - placeholder = { Text(stringResource(R.string.stun_password)) }, + placeholder = { Text(stunPasswordTitle) }, onValueChange = { viewModel.stunPass.value = it }, singleLine = true, visualTransformation = if (showPassword.value) @@ -736,12 +780,12 @@ private fun AccountContent( modifier = Modifier .fillMaxWidth() .clickable { - alertTitle.value = ctx.getString(R.string.stun_password) - alertMessage.value = ctx.getString(R.string.stun_password_help) + alertTitle.value = stunPasswordTitle + alertMessage.value = stunPasswordHelp showAlert.value = true }, textStyle = TextStyle(fontSize = 18.sp), - label = { Text(stringResource(R.string.stun_password)) }, + label = { Text(stunPasswordTitle) }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text) ) } @@ -749,18 +793,20 @@ private fun AccountContent( @Composable fun RtcpMux() { + val rtcpMuxTitle = stringResource(R.string.rtcp_mux) + val rtcpMuxHelp = stringResource(R.string.rtcp_mux_help) Row( Modifier.fillMaxWidth().padding(end = 10.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Start ) { val rtcpMux by viewModel.rtcpMux.collectAsState() - Text(text = stringResource(R.string.rtcp_mux), + Text(text = rtcpMuxTitle, modifier = Modifier .weight(1f) .clickable { - alertTitle.value = ctx.getString(R.string.rtcp_mux) - alertMessage.value = ctx.getString(R.string.rtcp_mux_help) + alertTitle.value = rtcpMuxTitle + alertMessage.value = rtcpMuxHelp showAlert.value = true }, fontSize = 18.sp @@ -774,18 +820,21 @@ private fun AccountContent( @Composable fun Rel100() { + val rel100Title = stringResource(R.string.rel_100) + val rel100Help = stringResource(R.string.rel_100_help) Row( Modifier.fillMaxWidth().padding(end = 10.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Start ) { val rel100 by viewModel.rel100.collectAsState() - Text(text = stringResource(R.string.rel_100), + Text( + text = rel100Title, modifier = Modifier .weight(1f) .clickable { - alertTitle.value = ctx.getString(R.string.rel_100) - alertMessage.value = ctx.getString(R.string.rel_100_help) + alertTitle.value = rel100Title + alertMessage.value = rel100Help showAlert.value = true }, fontSize = 18.sp @@ -799,21 +848,26 @@ private fun AccountContent( @Composable fun Dtmf() { + val dtmfModeTitle = stringResource(R.string.dtmf_mode) + val dtmfModeHelp = stringResource(R.string.dtmf_mode_help) + val dtmfInbandText = stringResource(R.string.dtmf_inband) + val dtmfInfoText = stringResource(R.string.dtmf_info) + val dtmfAutoText = stringResource(R.string.dtmf_auto) val dtmfMode by viewModel.dtmfMode.collectAsState() Row( Modifier.fillMaxWidth().padding(end = 10.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Start ) { - val dtmfModeMap = mapOf(Api.DTMFMODE_RTP_EVENT to ctx.getString(R.string.dtmf_inband), - Api.DTMFMODE_SIP_INFO to ctx.getString(R.string.dtmf_info), - Api.DTMFMODE_AUTO to ctx.getString(R.string.dtmf_auto)) - Text(text = stringResource(R.string.dtmf_mode), + val dtmfModeMap = mapOf(Api.DTMFMODE_RTP_EVENT to dtmfInbandText, + Api.DTMFMODE_SIP_INFO to dtmfInfoText, + Api.DTMFMODE_AUTO to dtmfAutoText) + Text(text = dtmfModeTitle, modifier = Modifier .weight(1f) .clickable { - alertTitle.value = ctx.getString(R.string.dtmf_mode) - alertMessage.value = ctx.getString(R.string.dtmf_mode_help) + alertTitle.value = dtmfModeTitle + alertMessage.value = dtmfModeHelp showAlert.value = true }, fontSize = 18.sp @@ -856,22 +910,27 @@ private fun AccountContent( } } + val manualText = stringResource(R.string.manual) + val autoText = stringResource(R.string.auto) + @Composable fun Answer() { + val answerModeTitle = stringResource(R.string.answer_mode) + val answerModeHelp = stringResource(R.string.answer_mode_help) val answerMode by viewModel.answerMode.collectAsState() Row( Modifier.fillMaxWidth().padding(end = 10.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Start ) { - val answerModeMap = mapOf(Api.ANSWERMODE_MANUAL to ctx.getString(R.string.manual), - Api.ANSWERMODE_AUTO to ctx.getString(R.string.auto)) - Text(text = stringResource(R.string.answer_mode), + val answerModeMap = mapOf(Api.ANSWERMODE_MANUAL to manualText, + Api.ANSWERMODE_AUTO to autoText) + Text(text = answerModeTitle, modifier = Modifier .weight(1f) .clickable { - alertTitle.value = ctx.getString(R.string.answer_mode) - alertMessage.value = ctx.getString(R.string.answer_mode_help) + alertTitle.value = answerModeTitle + alertMessage.value = answerModeHelp showAlert.value = true }, fontSize = 18.sp @@ -912,20 +971,22 @@ private fun AccountContent( @Composable fun Redirect() { + val redirectModeTitle = stringResource(R.string.redirect_mode) + val redirectModeHelp = stringResource(R.string.redirect_mode_help) val autoRedirect by viewModel.autoRedirect.collectAsState() Row( Modifier.fillMaxWidth().padding(end = 10.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Start ) { - val redirectModeMap = mapOf(false to ctx.getString(R.string.manual), - true to ctx.getString(R.string.auto)) - Text(text = stringResource(R.string.redirect_mode), + val redirectModeMap = mapOf(false to manualText, + true to autoText) + Text(text = redirectModeTitle, modifier = Modifier .weight(1f) .clickable { - alertTitle.value = ctx.getString(R.string.redirect_mode) - alertMessage.value = ctx.getString(R.string.redirect_mode_help) + alertTitle.value = redirectModeTitle + alertMessage.value = redirectModeHelp showAlert.value = true }, fontSize = 18.sp @@ -968,18 +1029,20 @@ private fun AccountContent( @Composable fun BlockUnknown() { + val blockUnknownTitle = stringResource(R.string.block_unknown) + val blockUnknownHelp = stringResource(R.string.block_unknown_help) val block by viewModel.blockUnknown.collectAsState() Row( Modifier.fillMaxWidth().padding(end = 10.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Start ) { - Text(text = stringResource(R.string.block_unknown), + Text(text = blockUnknownTitle, modifier = Modifier .weight(1f) .clickable { - alertTitle.value = ctx.getString(R.string.block_unknown) - alertMessage.value = ctx.getString(R.string.block_unknown_help) + alertTitle.value = blockUnknownTitle + alertMessage.value = blockUnknownHelp showAlert.value = true }, fontSize = 18.sp @@ -993,6 +1056,8 @@ private fun AccountContent( @Composable fun Voicemail() { + val voicemailUriTitle = stringResource(R.string.voicemail_uri) + val voicemailUriHelp = stringResource(R.string.voicemain_uri_help) val vmUri by viewModel.vmUri.collectAsState() Row( Modifier.fillMaxWidth().padding(end = 10.dp), @@ -1001,18 +1066,18 @@ private fun AccountContent( ) { OutlinedTextField( value = vmUri, - placeholder = { Text(stringResource(R.string.voicemail_uri)) }, + placeholder = { Text(voicemailUriTitle) }, onValueChange = { viewModel.vmUri.value = it }, modifier = Modifier .fillMaxWidth() .clickable { - alertTitle.value = ctx.getString(R.string.voicemail_uri) - alertMessage.value = ctx.getString(R.string.voicemain_uri_help) + alertTitle.value = voicemailUriTitle + alertMessage.value = voicemailUriHelp showAlert.value = true }, singleLine = true, textStyle = TextStyle(fontSize = 18.sp), - label = { Text(stringResource(R.string.voicemail_uri)) }, + label = { Text(voicemailUriTitle) }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text) ) } @@ -1020,6 +1085,8 @@ private fun AccountContent( @Composable fun CountryCode() { + val countryCodeTitle = stringResource(R.string.country_code) + val countryCodeHelp = stringResource(R.string.country_code_help) val countryCode by viewModel.countryCode.collectAsState() Row( Modifier.fillMaxWidth().padding(top = 8.dp, end = 10.dp), @@ -1028,18 +1095,18 @@ private fun AccountContent( ) { OutlinedTextField( value = countryCode, - placeholder = { Text(stringResource(R.string.country_code)) }, + placeholder = { Text(countryCodeTitle) }, onValueChange = { viewModel.countryCode.value = it }, modifier = Modifier .fillMaxWidth() .clickable { - alertTitle.value = ctx.getString(R.string.country_code) - alertMessage.value = ctx.getString(R.string.country_code_help) + alertTitle.value = countryCodeTitle + alertMessage.value = countryCodeHelp showAlert.value = true }, singleLine = true, textStyle = TextStyle(fontSize = 18.sp), - label = { Text(stringResource(R.string.country_code)) }, + label = { Text(countryCodeTitle) }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text) ) } @@ -1047,6 +1114,8 @@ private fun AccountContent( @Composable fun TelProvider() { + val telephonyProviderTitle = stringResource(R.string.telephony_provider) + val telephonyProviderHelp = stringResource(R.string.telephony_provider_help) val telProvider by viewModel.telProvider.collectAsState() Row( Modifier.fillMaxWidth().padding(top = 8.dp, end = 10.dp), @@ -1055,18 +1124,18 @@ private fun AccountContent( ) { OutlinedTextField( value = telProvider, - placeholder = { Text(stringResource(R.string.telephony_provider)) }, + placeholder = { Text(telephonyProviderTitle) }, onValueChange = { viewModel.telProvider.value = it }, modifier = Modifier .fillMaxWidth() .clickable { - alertTitle.value = ctx.getString(R.string.telephony_provider) - alertMessage.value = ctx.getString(R.string.telephony_provider_help) + alertTitle.value = telephonyProviderTitle + alertMessage.value = telephonyProviderHelp showAlert.value = true }, singleLine = true, textStyle = TextStyle(fontSize = 18.sp), - label = { Text(stringResource(R.string.telephony_provider)) }, + label = { Text(telephonyProviderTitle) }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text) ) } @@ -1074,18 +1143,20 @@ private fun AccountContent( @Composable fun NumericKeypad() { + val numericKeypadTitle = stringResource(R.string.numeric_keypad) + val numericKeypadHelp = stringResource(R.string.numeric_keypad_help) val numericKeypad by viewModel.numericKeypad.collectAsState() Row( Modifier.fillMaxWidth().padding(end = 10.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Start ) { - Text(text = stringResource(R.string.numeric_keypad), + Text(text = numericKeypadTitle, modifier = Modifier .weight(1f) .clickable { - alertTitle.value = ctx.getString(R.string.numeric_keypad) - alertMessage.value = ctx.getString(R.string.numeric_keypad_help) + alertTitle.value = numericKeypadTitle + alertMessage.value = numericKeypadHelp showAlert.value = true }, fontSize = 18.sp @@ -1099,18 +1170,20 @@ private fun AccountContent( @Composable fun DefaultAccount() { + val defaultAccountTitle = stringResource(R.string.default_account) + val defaultAccountHelp = stringResource(R.string.default_account_help) val defaultAccount by viewModel.defaultAccount.collectAsState() Row( Modifier.fillMaxWidth().padding(end = 10.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Start ) { - Text(text = stringResource(R.string.default_account), + Text(text = defaultAccountTitle, modifier = Modifier .weight(1f) .clickable { - alertTitle.value = ctx.getString(R.string.default_account) - alertMessage.value = ctx.getString(R.string.default_account_help) + alertTitle.value = defaultAccountTitle + alertMessage.value = defaultAccountHelp showAlert.value = true }, fontSize = 18.sp @@ -1153,7 +1226,10 @@ private fun AccountContent( AskPassword(ctx, navController, ua) Outbound() Register() - RegInt() + if (viewModel.register.collectAsState().value) { + RegInt() + CheckOrigin() + } AudioCodecs(navController, aor) MediaEnc() MediaNat() @@ -1177,7 +1253,9 @@ private fun AccountContent( } private fun checkOnClick(ctx: Context, viewModel: AccountViewModel, ua: UserAgent): Boolean { + val acc = ua.account + val noticeTitle = ctx.getString(R.string.notice) val nn = viewModel.nickName.value.trim() if (nn != acc.nickName) { @@ -1187,14 +1265,14 @@ private fun checkOnClick(ctx: Context, viewModel: AccountViewModel, ua: UserAgen Log.d(TAG, "New nickname is ${acc.nickName}") } else { - alertTitle.value = ctx.getString(R.string.notice) + alertTitle.value = noticeTitle alertMessage.value = String.format(ctx.getString(R.string.non_unique_account_nickname), nn) showAlert.value = true return false } } else { - alertTitle.value = ctx.getString(R.string.notice) + alertTitle.value = noticeTitle alertMessage.value = String.format(ctx.getString(R.string.invalid_account_nickname), nn) showAlert.value = true return false @@ -1212,7 +1290,7 @@ private fun checkOnClick(ctx: Context, viewModel: AccountViewModel, ua: UserAgen } } else { - alertTitle.value = ctx.getString(R.string.notice) + alertTitle.value = noticeTitle alertMessage.value = String.format(ctx.getString(R.string.invalid_display_name), dn) showAlert.value = true return false @@ -1233,7 +1311,7 @@ private fun checkOnClick(ctx: Context, viewModel: AccountViewModel, ua: UserAgen } } else { - alertTitle.value = ctx.getString(R.string.notice) + alertTitle.value = noticeTitle alertMessage.value = String.format(ctx.getString(R.string.invalid_authentication_username), au) showAlert.value = true return false @@ -1254,7 +1332,7 @@ private fun checkOnClick(ctx: Context, viewModel: AccountViewModel, ua: UserAgen BaresipService.aorPasswords.remove(acc.aor) } else { - alertTitle.value = ctx.getString(R.string.notice) + alertTitle.value = noticeTitle alertMessage.value = String.format(ctx.getString(R.string.invalid_authentication_password), ap) showAlert.value = true return false @@ -1280,7 +1358,7 @@ private fun checkOnClick(ctx: Context, viewModel: AccountViewModel, ua: UserAgen ob.add(ob1) } else { - alertTitle.value = ctx.getString(R.string.notice) + alertTitle.value = noticeTitle alertMessage.value = String.format(ctx.getString(R.string.invalid_proxy_server_uri), ob1) showAlert.value = true return false @@ -1293,7 +1371,7 @@ private fun checkOnClick(ctx: Context, viewModel: AccountViewModel, ua: UserAgen if (checkOutboundUri(ob2)) ob.add(ob2) else { - alertTitle.value = ctx.getString(R.string.notice) + alertTitle.value = noticeTitle alertMessage.value = String.format(ctx.getString(R.string.invalid_proxy_server_uri), ob2) showAlert.value = true return false @@ -1324,7 +1402,7 @@ private fun checkOnClick(ctx: Context, viewModel: AccountViewModel, ua: UserAgen 0 } if (regInt !in 60..3600) { - alertTitle.value = ctx.getString(R.string.notice) + alertTitle.value = noticeTitle alertMessage.value = String.format(ctx.getString(R.string.invalid_reg_int), "$regInt") showAlert.value = true return false @@ -1347,6 +1425,13 @@ private fun checkOnClick(ctx: Context, viewModel: AccountViewModel, ua: UserAgen acc.configuredRegInt = regInt } + if (acc.regint == 0) + Api.account_set_check_origin(ua.account.accp, false) + else { + Api.account_set_check_origin(ua.account.accp, viewModel.checkOrigin.value) + acc.checkOrigin = Api.account_check_origin(ua.account.accp) + } + val newMediaEnc = viewModel.mediaEnc.value if (newMediaEnc != acc.mediaEnc) { if (Api.account_set_mediaenc(acc.accp, newMediaEnc) == 0) { @@ -1402,7 +1487,7 @@ private fun checkOnClick(ctx: Context, viewModel: AccountViewModel, ua: UserAgen Log.e(TAG, "Setting of STUN/TURN user $newStunUser failed") } else { - alertTitle.value = ctx.getString(R.string.notice) + alertTitle.value = noticeTitle alertMessage.value = String.format(ctx.getString(R.string.invalid_stun_username), newStunUser) showAlert.value = true @@ -1419,7 +1504,7 @@ private fun checkOnClick(ctx: Context, viewModel: AccountViewModel, ua: UserAgen Log.e(TAG, "Setting of stun pass failed") } else { - alertTitle.value = ctx.getString(R.string.notice) + alertTitle.value = noticeTitle alertMessage.value = String.format(ctx.getString(R.string.invalid_stun_password), newStunPass) showAlert.value = true @@ -1487,7 +1572,7 @@ private fun checkOnClick(ctx: Context, viewModel: AccountViewModel, ua: UserAgen if (!newVmUri.startsWith("sip:")) newVmUri = "sip:$newVmUri" if (!newVmUri.contains("@")) newVmUri = "$newVmUri@${acc.host()}" if (!Utils.checkUri(newVmUri)) { - alertTitle.value = ctx.getString(R.string.notice) + alertTitle.value = noticeTitle alertMessage.value = String.format(ctx.getString(R.string.invalid_sip_or_tel_uri), newVmUri) showAlert.value = true @@ -1517,7 +1602,7 @@ private fun checkOnClick(ctx: Context, viewModel: AccountViewModel, ua: UserAgen val hostPart = viewModel.telProvider.value.trim() if (hostPart != acc.telProvider) { if (hostPart != "" && !Utils.checkHostPortParams(hostPart)) { - alertTitle.value = ctx.getString(R.string.notice) + alertTitle.value = noticeTitle alertMessage.value = String.format(ctx.getString(R.string.invalid_sip_uri_hostpart), hostPart) showAlert.value = true return false @@ -1534,6 +1619,8 @@ private fun checkOnClick(ctx: Context, viewModel: AccountViewModel, ua: UserAgen if (viewModel.defaultAccount.value) ua.makeDefault() + Api.account_debug(acc.accp) + Account.saveAccounts() if (acc.authUser != "" && BaresipService.aorPasswords[acc.aor] == NO_AUTH_PASS) { @@ -1599,8 +1686,11 @@ private fun initAccountFromConfig(acc: Account, onConfigLoaded: () -> Unit) { 900 } - "register" -> + "register" -> { acc.regint = if (text == "yes") acc.configuredRegInt else 0 + if (acc.regint > 0) + acc.checkOrigin = true + } "audio-codec" -> if (text in audioCodecs) diff --git a/app/src/main/kotlin/com/tutpro/baresip/AccountViewModel.kt b/app/src/main/kotlin/com/tutpro/baresip/AccountViewModel.kt index 23f8325f..907f1359 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/AccountViewModel.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/AccountViewModel.kt @@ -13,6 +13,7 @@ class AccountViewModel: ViewModel() { val outbound2 = MutableStateFlow("") val register = MutableStateFlow(false) val regInt = MutableStateFlow("") + val checkOrigin = MutableStateFlow(false) val mediaEnc = MutableStateFlow("") val mediaNat = MutableStateFlow("") val stunServer = MutableStateFlow("") @@ -45,6 +46,7 @@ class AccountViewModel: ViewModel() { outbound2.value = if (acc.outbound.size > 1) acc.outbound[1] else "" register.value = acc.regint > 0 regInt.value = acc.configuredRegInt.toString() + checkOrigin.value = acc.checkOrigin mediaEnc.value = acc.mediaEnc mediaNat.value = acc.mediaNat stunServer.value = acc.stunServer diff --git a/app/src/main/kotlin/com/tutpro/baresip/AccountsScreen.kt b/app/src/main/kotlin/com/tutpro/baresip/AccountsScreen.kt index b36c0310..c9a40922 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/AccountsScreen.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/AccountsScreen.kt @@ -114,8 +114,6 @@ fun AccountsScreen(navController: NavController) { @Composable fun AccountsContent(contentPadding: PaddingValues, navController: NavController) { - val ctx = LocalContext.current - val showDialog = remember { mutableStateOf(false) } val message = remember { mutableStateOf("") } val positiveAction = remember { mutableStateOf({}) } @@ -166,13 +164,11 @@ fun AccountsContent(contentPadding: PaddingValues, navController: NavController) navController.navigate("account/$aor/old") } ) + val deleteAccountMessage = stringResource(R.string.delete_account) SmallFloatingActionButton( modifier = Modifier.padding(end = 8.dp), onClick = { - message.value = String.format( - ctx.getString(R.string.delete_account), - text - ) + message.value = String.format(deleteAccountMessage, text) positiveAction.value = { CallHistoryNew.clear(aor) Message.clearMessagesOfAor(aor) @@ -237,7 +233,7 @@ fun NewAccount(navController: NavController) { } val ua = UserAgent.uaAlloc( - "<$aor>;stunserver=\"stun:stun.l.google.com:19302\";regq=0.5;pubint=0;regint=0;mwi=no" + "<$aor>;stunserver=\"stun:stun.l.google.com:19302\";regq=0.5;pubint=0;regint=0;check_origin=no;mwi=no" ) if (ua == null) { alertTitle.value = ctx.getString(R.string.notice) @@ -246,8 +242,8 @@ fun NewAccount(navController: NavController) { return null } - // Api.account_debug(ua.account.accp) val acc = ua.account + acc.checkOrigin = true Log.d(TAG, "Allocated UA ${ua.uap} with SIP URI ${acc.luri}") Account.saveAccounts() return acc @@ -263,6 +259,8 @@ fun NewAccount(navController: NavController) { verticalAlignment = Alignment.CenterVertically ) { val ctx = LocalContext.current + val newAccountTitle = stringResource(R.string.new_account) + val accountsHelp = stringResource(R.string.accounts_help) OutlinedTextField( value = newAor, placeholder = { Text(text = stringResource(R.string.new_account)) }, @@ -272,8 +270,8 @@ fun NewAccount(navController: NavController) { .padding(end = 8.dp) .verticalScroll(rememberScrollState()) .clickable { - alertTitle.value = ctx.getString(R.string.new_account) - alertMessage.value = ctx.getString(R.string.accounts_help) + alertTitle.value = newAccountTitle + alertMessage.value = accountsHelp showAlert.value = true }, singleLine = false, diff --git a/app/src/main/kotlin/com/tutpro/baresip/Api.kt b/app/src/main/kotlin/com/tutpro/baresip/Api.kt index fc86325f..dd1e52b9 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/Api.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/Api.kt @@ -34,6 +34,8 @@ object Api { external fun account_audio_codec(acc: Long, ix: Int): String external fun account_regint(acc: Long): Int external fun account_set_regint(acc: Long, regint: Int): Int + external fun account_check_origin(acc: Long): Boolean + external fun account_set_check_origin(acc: Long, check: Boolean) external fun account_stun_uri(acc: Long): String external fun account_set_stun_uri(acc: Long, uri: String): Int external fun account_stun_user(acc: Long): String diff --git a/app/src/main/kotlin/com/tutpro/baresip/SettingsScreen.kt b/app/src/main/kotlin/com/tutpro/baresip/SettingsScreen.kt index 768eb259..6502b0be 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/SettingsScreen.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/SettingsScreen.kt @@ -237,12 +237,19 @@ private fun SettingsContent( onRestartApp: () -> Unit ) { + val alertTitleText = stringResource(R.string.alert) + val errorTitleText = stringResource(R.string.error) + val noticeTitleText = stringResource(R.string.notice) + val confirmationText = stringResource(R.string.confirmation) + val okButtonText = stringResource(R.string.ok) + val cancelButtonText = stringResource(R.string.cancel) + if (showAlert.value) { AlertDialog( showDialog = showAlert, title = alertTitle.value, message = alertMessage.value, - positiveButtonText = stringResource(R.string.ok), + positiveButtonText = okButtonText, ) } @@ -259,18 +266,21 @@ private fun SettingsContent( @Composable fun StartAutomatically() { + val startAutomaticallyTitle = stringResource(R.string.start_automatically) + val startAutomaticallyHelp = stringResource(R.string.start_automatically_help) + val appearOnTopPermissionMessage = stringResource(R.string.appear_on_top_permission) Row( Modifier.fillMaxWidth().padding(end = 10.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Start ) { val ctx = LocalContext.current - Text(text = stringResource(R.string.start_automatically), + Text(text = startAutomaticallyTitle, modifier = Modifier .weight(1f) .clickable { - alertTitle.value = ctx.getString(R.string.start_automatically) - alertMessage.value = ctx.getString(R.string.start_automatically_help) + alertTitle.value = startAutomaticallyTitle + alertMessage.value = startAutomaticallyHelp showAlert.value = true }, fontSize = 18.sp @@ -281,14 +291,14 @@ private fun SettingsContent( onCheckedChange = { if (it) { if (!isAppearOnTopPermissionGranted(ctx)) { - dialogTitle.value = ctx.getString(R.string.notice) - dialogMessage.value = ctx.getString(R.string.appear_on_top_permission) - positiveText.value = ctx.getString(R.string.ok) + dialogTitle.value = noticeTitleText + dialogMessage.value = appearOnTopPermissionMessage + positiveText.value = okButtonText onPositiveClicked.value = { val intent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION) ctx.startActivity(intent) } - negativeText.value = ctx.getString(R.string.cancel) + negativeText.value = cancelButtonText onNegativeClicked.value = { negativeText.value = "" } @@ -306,50 +316,21 @@ private fun SettingsContent( } @Composable - fun ListenAddress() { + fun AddressFamily() { + val addressFamilyTitle = stringResource(R.string.address_family) + val addressFamilyHelp = stringResource(R.string.address_family_help) Row( Modifier.fillMaxWidth().padding(end = 10.dp), verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.Start, - ) { - val ctx = LocalContext.current - val listenAddress by viewModel.listenAddress.collectAsState() - OutlinedTextField( - value = listenAddress, - placeholder = { Text(stringResource(R.string._0_0_0_0_5060)) }, - onValueChange = { - viewModel.listenAddress.value = it - }, - modifier = Modifier - .fillMaxWidth() - .clickable { - alertTitle.value = ctx.getString(R.string.listen_address) - alertMessage.value = ctx.getString(R.string.listen_address_help) - showAlert.value = true - }, - singleLine = true, - textStyle = androidx.compose.ui.text.TextStyle(fontSize = 18.sp), - label = { Text(stringResource(R.string.listen_address)) }, - keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text) - ) - } - } - - @Composable - fun AddressFamily() { - Row( - Modifier.fillMaxWidth().padding(top = 12.dp).padding(end = 10.dp), - verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Start ) { - val ctx = LocalContext.current val addressFamily by viewModel.addressFamily.collectAsState() - Text(text = stringResource(R.string.address_family), + Text(text = addressFamilyTitle, modifier = Modifier .weight(1f) .clickable { - alertTitle.value = ctx.getString(R.string.address_family) - alertMessage.value = ctx.getString(R.string.address_family_help) + alertTitle.value = addressFamilyTitle + alertMessage.value = addressFamilyHelp showAlert.value = true }, fontSize = 18.sp @@ -397,14 +378,46 @@ private fun SettingsContent( } } + @Composable + fun ListenAddress() { + val listenAddressTitle = stringResource(R.string.listen_address) + val listenAddressHelp = stringResource(R.string.listen_address_help) + Row( + Modifier.fillMaxWidth().padding(end = 10.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.Start, + ) { + val listenAddress by viewModel.listenAddress.collectAsState() + OutlinedTextField( + value = listenAddress, + placeholder = { Text(stringResource(R.string._0_0_0_0_5060)) }, + onValueChange = { + viewModel.listenAddress.value = it + }, + modifier = Modifier + .fillMaxWidth() + .clickable { + alertTitle.value = listenAddressTitle + alertMessage.value = listenAddressHelp + showAlert.value = true + }, + singleLine = true, + textStyle = androidx.compose.ui.text.TextStyle(fontSize = 18.sp), + label = { Text(listenAddressTitle) }, + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text) + ) + } + } + @Composable fun TransportProtocols() { + val transportProtocolsTitle = stringResource(R.string.transport_protocols) + val transportProtocolsHelp = stringResource(R.string.transport_protocols_help) Row( Modifier.fillMaxWidth().padding(end = 10.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Start ) { - val ctx = LocalContext.current val transportProtocols by viewModel.transportProtocols.collectAsState() OutlinedTextField( value = transportProtocols, @@ -414,12 +427,12 @@ private fun SettingsContent( modifier = Modifier .fillMaxWidth() .clickable { - alertTitle.value = ctx.getString(R.string.transport_protocols) - alertMessage.value = ctx.getString(R.string.transport_protocols_help) + alertTitle.value = transportProtocolsTitle + alertMessage.value = transportProtocolsHelp showAlert.value = true }, textStyle = androidx.compose.ui.text.TextStyle(fontSize = 18.sp), - label = { Text(stringResource(R.string.transport_protocols)) }, + label = { Text(transportProtocolsTitle) }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text) ) } @@ -427,12 +440,13 @@ private fun SettingsContent( @Composable fun DnsServers() { + val dnsServersTitle = stringResource(R.string.dns_servers) + val dnsServersHelp = stringResource(R.string.dns_servers_help) Row( Modifier.fillMaxWidth().padding(end = 10.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Start ) { - val ctx = LocalContext.current val dnsServers by viewModel.dnsServers.collectAsState() OutlinedTextField( value = dnsServers, @@ -442,12 +456,12 @@ private fun SettingsContent( modifier = Modifier .fillMaxWidth() .clickable { - alertTitle.value = ctx.getString(R.string.dns_servers) - alertMessage.value = ctx.getString(R.string.dns_servers_help) + alertTitle.value = dnsServersTitle + alertMessage.value = dnsServersHelp showAlert.value = true }, textStyle = androidx.compose.ui.text.TextStyle(fontSize = 18.sp), - label = { Text(stringResource(R.string.dns_servers)) }, + label = { Text(dnsServersTitle) }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text) ) } @@ -458,6 +472,10 @@ private fun SettingsContent( val ctx = LocalContext.current + val readCertError = stringResource(R.string.read_cert_error) + val tlsCertificateFileTitle = stringResource(R.string.tls_certificate_file) + val tlsCertificateFileHelp = stringResource(R.string.tls_certificate_file_help) + val requestPermissionLauncher = rememberLauncherForActivityResult( contract = ActivityResultContracts.RequestPermission() ) {} @@ -478,8 +496,8 @@ private fun SettingsContent( save = true restart = true } catch (e: Error) { - alertTitle.value = ctx.getString(R.string.error) - alertMessage.value = ctx.getString(R.string.read_cert_error) + ": " + e.message + alertTitle.value = errorTitleText + alertMessage.value = readCertError + ": " + e.message showAlert.value = true viewModel.tlsCertificateFile.value = false } @@ -499,12 +517,12 @@ private fun SettingsContent( horizontalArrangement = Arrangement.Start ) { val ctx = LocalContext.current - Text(text = stringResource(R.string.tls_certificate_file), + Text(text = tlsCertificateFileTitle, modifier = Modifier .weight(1f) .clickable { - alertTitle.value = ctx.getString(R.string.tls_certificate_file) - alertMessage.value = ctx.getString(R.string.tls_certificate_file_help) + alertTitle.value = tlsCertificateFileTitle + alertMessage.value = tlsCertificateFileHelp showAlert.value = true }, fontSize = 18.sp @@ -525,8 +543,8 @@ private fun SettingsContent( val downloadsPath = Utils.downloadsPath("cert.pem") val content = Utils.getFileContents(downloadsPath) if (content == null) { - alertTitle.value = ctx.getString(R.string.error) - alertMessage.value = ctx.getString(R.string.read_cert_error) + alertTitle.value = errorTitleText + alertMessage.value = readCertError showAlert.value = true return@Switch } @@ -569,17 +587,18 @@ private fun SettingsContent( @Composable fun VerifyServer() { + val verifyServerTitle = stringResource(R.string.verify_server) + val verifyServerHelp = stringResource(R.string.verify_server_help) Row( Modifier.fillMaxWidth().padding(end = 10.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Start ) { - val ctx = LocalContext.current - Text(text = stringResource(R.string.verify_server), + Text(text = verifyServerTitle, modifier = Modifier.weight(1f) .clickable { - alertTitle.value = ctx.getString(R.string.verify_server) - alertMessage.value = ctx.getString(R.string.verify_server_help) + alertTitle.value = verifyServerTitle + alertMessage.value = verifyServerHelp showAlert.value = true }, fontSize = 18.sp @@ -597,6 +616,11 @@ private fun SettingsContent( val ctx = LocalContext.current + val tlsCaFileTitle = stringResource(R.string.tls_ca_file) + val tlsCaFileHelp = stringResource(R.string.tls_ca_file_help) + val readCaCertsError = stringResource(R.string.read_ca_certs_error) + val noReadPermissionMessage = stringResource(R.string.no_read_permission) + val requestPermissionLauncher = rememberLauncherForActivityResult( contract = ActivityResultContracts.RequestPermission() ) {} @@ -613,8 +637,8 @@ private fun SettingsContent( inputStream.close() restart = true } catch (e: Error) { - alertTitle.value = ctx.getString(R.string.error) - alertMessage.value = ctx.getString(R.string.read_ca_certs_error) + ": " + e.message + alertTitle.value = errorTitleText + alertMessage.value = readCaCertsError + ": " + e.message showAlert.value = true viewModel.caFile.value = false } @@ -630,11 +654,11 @@ private fun SettingsContent( horizontalArrangement = Arrangement.Start ) { val ctx = LocalContext.current - Text(text = stringResource(R.string.tls_ca_file), + Text(text = tlsCaFileTitle, modifier = Modifier.weight(1f) .clickable { - alertTitle.value = ctx.getString(R.string.tls_ca_file) - alertMessage.value = ctx.getString(R.string.tls_ca_file_help) + alertTitle.value = tlsCaFileTitle + alertMessage.value = tlsCaFileHelp showAlert.value = true }, fontSize = 18.sp @@ -654,8 +678,8 @@ private fun SettingsContent( val downloadsPath = Utils.downloadsPath("ca_certs.crt") val content = Utils.getFileContents(downloadsPath) if (content == null) { - alertTitle.value = ctx.getString(R.string.error) - alertMessage.value = ctx.getString(R.string.read_ca_certs_error) + alertTitle.value = errorTitleText + alertMessage.value = readCaCertsError showAlert.value = true return@Switch } @@ -664,9 +688,9 @@ private fun SettingsContent( restart = true } shouldShowRequestPermissionRationale(activity, permission) -> { - dialogTitle.value = ctx.getString(R.string.notice) - dialogMessage.value = ctx.getString(R.string.no_read_permission) - positiveText.value = ctx.getString(R.string.ok) + dialogTitle.value = noticeTitleText + dialogMessage.value = noReadPermissionMessage + positiveText.value = okButtonText onPositiveClicked.value = { requestPermissionLauncher.launch(permission) } @@ -691,26 +715,27 @@ private fun SettingsContent( @Composable fun UserAgent() { + val userAgentTitle = stringResource(R.string.user_agent) + val userAgentHelp = stringResource(R.string.user_agent_help) Row( Modifier.fillMaxWidth().padding(end = 10.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Start ) { - val ctx = LocalContext.current val userAgent by viewModel.userAgent.collectAsState() OutlinedTextField( value = userAgent, - placeholder = { Text(stringResource(R.string.user_agent)) }, + placeholder = { Text(userAgentTitle) }, onValueChange = { viewModel.userAgent.value = it }, modifier = Modifier .fillMaxWidth() .clickable { - alertTitle.value = ctx.getString(R.string.user_agent) - alertMessage.value = ctx.getString(R.string.user_agent_help) + alertTitle.value = userAgentTitle + alertMessage.value = userAgentHelp showAlert.value = true }, textStyle = androidx.compose.ui.text.TextStyle(fontSize = 18.sp), - label = { Text(stringResource(R.string.user_agent)) }, + label = { Text(userAgentTitle) }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text) ) } @@ -735,6 +760,14 @@ private fun SettingsContent( @Composable fun Contacts(activity: Activity) { + val contactsTitle = stringResource(R.string.contacts) + val contactsHelp = stringResource(R.string.contacts_help) + val consentRequestTitle = stringResource(R.string.consent_request) + val contactsConsentMessage = stringResource(R.string.contacts_consent) + val positiveButtonText = stringResource(R.string.accept) + val negativeButtonText = stringResource(R.string.deny) + val both = stringResource(R.string.both) + val noAndroidContactsMessage = stringResource(R.string.no_android_contacts) val showAlertDialog = remember { mutableStateOf(false) } Row( Modifier.fillMaxWidth().padding(top = 12.dp).padding(end = 10.dp), @@ -742,12 +775,12 @@ private fun SettingsContent( horizontalArrangement = Arrangement.Start ) { val ctx = LocalContext.current - Text(text = stringResource(R.string.contacts), + Text(text = contactsTitle, modifier = Modifier .weight(1f) .clickable { - alertTitle.value = ctx.getString(R.string.contacts) - alertMessage.value = ctx.getString(R.string.contacts_help) + alertTitle.value = contactsTitle + alertMessage.value = contactsHelp showAlert.value = true }, fontSize = 18.sp @@ -758,7 +791,7 @@ private fun SettingsContent( val contactNames = listOf( "baresip", "Android", - ctx.getString(R.string.both) + both ) val contactsMode by viewModel.contactsMode.collectAsState() val contactValues = listOf("baresip", "android", "both") @@ -797,9 +830,9 @@ private fun SettingsContent( isDropDownExpanded.value = false val mode = contactValues[index] if (mode != "baresip" && !Utils.checkPermissions(ctx, contactsPermissions)) { - dialogTitle.value = ctx.getString(R.string.consent_request) - dialogMessage.value = ctx.getString(R.string.contacts_consent) - positiveText.value = ctx.getString(R.string.accept) + dialogTitle.value = consentRequestTitle + dialogMessage.value = contactsConsentMessage + positiveText.value = positiveButtonText onPositiveClicked.value = { showDialog.value = false viewModel.contactsMode.value = mode @@ -831,7 +864,7 @@ private fun SettingsContent( ) } } - negativeText.value = ctx.getString(R.string.deny) + negativeText.value = negativeButtonText onNegativeClicked.value = { itemPosition.intValue = contactValues.indexOf(contactsMode) negativeText.value = "" @@ -851,9 +884,9 @@ private fun SettingsContent( if (showAlertDialog.value) AlertDialog( showDialog = showAlertDialog, - title = stringResource(R.string.notice), - message = stringResource(R.string.no_android_contacts), - positiveButtonText = stringResource(R.string.ok), + title = noticeTitleText, + message = noAndroidContactsMessage, + positiveButtonText = okButtonText, onPositiveClicked = { requestPermissionsLauncher.launch( arrayOf( Manifest.permission.READ_CONTACTS, @@ -867,7 +900,9 @@ private fun SettingsContent( } @Composable - fun Ringtone(ctx: Context) { + fun Ringtone() { + val ringToneTitle = stringResource(R.string.ringtone) + val selectRingToneMessage = stringResource(R.string.select_ringtone) val launcher = rememberLauncherForActivityResult( ActivityResultContracts.StartActivityForResult() ) { result: ActivityResult -> @@ -887,7 +922,7 @@ private fun SettingsContent( horizontalArrangement = Arrangement.Start ) { Text( - text = stringResource(R.string.ringtone), + text = ringToneTitle, modifier = Modifier .weight(1f) .clickable { @@ -898,7 +933,7 @@ private fun SettingsContent( ) intent.putExtra( RingtoneManager.EXTRA_RINGTONE_TITLE, - ctx.getString(R.string.select_ringtone) + selectRingToneMessage ) intent.putExtra( RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, @@ -916,6 +951,8 @@ private fun SettingsContent( @Composable fun BatteryOptimizations() { + val batteryOptimizationsTitle = stringResource(R.string.battery_optimizations) + val batteryOptimizationsHelp = stringResource(R.string.battery_optimizations_help) Row( Modifier.fillMaxWidth().padding(end = 10.dp), verticalAlignment = Alignment.CenterVertically, @@ -929,12 +966,12 @@ private fun SettingsContent( viewModel.batteryOptimizations.value = !powerManager.isIgnoringBatteryOptimizations(ctx.packageName) } - Text(text = stringResource(R.string.battery_optimizations), + Text(text = batteryOptimizationsTitle, modifier = Modifier .weight(1f) .clickable { - alertTitle.value = ctx.getString(R.string.battery_optimizations) - alertMessage.value = ctx.getString(R.string.battery_optimizations_help) + alertTitle.value = batteryOptimizationsTitle + alertMessage.value = batteryOptimizationsHelp showAlert.value = true }, fontSize = 18.sp @@ -953,18 +990,19 @@ private fun SettingsContent( @Composable fun DarkTheme() { + val darkThemeTitle = stringResource(R.string.dark_theme) + val darkThemeHelp = stringResource(R.string.dark_theme_help) Row( Modifier.fillMaxWidth().padding(end = 10.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Start ) { - val ctx = LocalContext.current - Text(text = stringResource(R.string.dark_theme), + Text(text = darkThemeTitle, modifier = Modifier .weight(1f) .clickable { - alertTitle.value = ctx.getString(R.string.dark_theme) - alertMessage.value = ctx.getString(R.string.dark_theme_help) + alertTitle.value = darkThemeTitle + alertMessage.value = darkThemeHelp showAlert.value = true }, fontSize = 18.sp @@ -979,17 +1017,18 @@ private fun SettingsContent( @Composable fun DynamicColors() { + val dynamicColorsTitle = stringResource(R.string.dynamic_colors) + val dynamicColorsHelp = stringResource(R.string.dynamic_colors_help) Row( Modifier.fillMaxWidth().padding(end = 10.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Start ) { - val ctx = LocalContext.current - Text(text = stringResource(R.string.dynamic_colors), + Text(text = dynamicColorsTitle, modifier = Modifier.weight(1f) .clickable { - alertTitle.value = ctx.getString(R.string.dynamic_colors) - alertMessage.value = ctx.getString(R.string.dynamic_colors_help) + alertTitle.value = dynamicColorsTitle + alertMessage.value = dynamicColorsHelp showAlert.value = true }, fontSize = 18.sp @@ -1004,18 +1043,19 @@ private fun SettingsContent( @Composable fun ColorBlind() { + val colorBlindTitle = stringResource(R.string.colorblind) + val colorBlindHelp = stringResource(R.string.colorblind_help) Row( Modifier.fillMaxWidth().padding(end = 10.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Start ) { - val ctx = LocalContext.current - Text(text = stringResource(R.string.colorblind), + Text(text = colorBlindTitle, modifier = Modifier .weight(1f) .clickable { - alertTitle.value = ctx.getString(R.string.colorblind) - alertMessage.value = ctx.getString(R.string.colorblind_help) + alertTitle.value = colorBlindTitle + alertMessage.value = colorBlindHelp showAlert.value = true }, fontSize = 18.sp @@ -1029,18 +1069,19 @@ private fun SettingsContent( } @Composable fun ProximitySensing() { + val proximitySensingTitle = stringResource(R.string.proximity_sensing) + val proximitySensingHelp = stringResource(R.string.proximity_sensing_help) Row( Modifier.fillMaxWidth().padding(end = 10.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Start ) { - val ctx = LocalContext.current - Text(text = stringResource(R.string.proximity_sensing), + Text(text = proximitySensingTitle, modifier = Modifier .weight(1f) .clickable { - alertTitle.value = ctx.getString(R.string.proximity_sensing) - alertMessage.value = ctx.getString(R.string.proximity_sensing_help) + alertTitle.value = proximitySensingTitle + alertMessage.value = proximitySensingHelp showAlert.value = true }, fontSize = 18.sp @@ -1056,18 +1097,21 @@ private fun SettingsContent( @RequiresApi(29) @Composable fun DefaultDialer() { + 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 = stringResource(R.string.default_phone_app), + Text(text = defaultPhoneAppTitle, modifier = Modifier .weight(1f) .clickable { - alertTitle.value = ctx.getString(R.string.default_phone_app) - alertMessage.value = ctx.getString(R.string.default_phone_app_help) + alertTitle.value = defaultPhoneAppTitle + alertMessage.value = defaultPhoneAppHelp showAlert.value = true }, fontSize = 18.sp @@ -1086,8 +1130,8 @@ private fun SettingsContent( viewModel.defaultDialer.value = it if (it) { if (!roleManager.isRoleAvailable(RoleManager.ROLE_DIALER)) { - alertTitle.value = ctx.getString(R.string.alert) - alertMessage.value = ctx.getString(R.string.dialer_role_not_available) + alertTitle.value = alertTitleText + alertMessage.value = dialerRoleNotAvailableMessage showAlert.value = true } else @@ -1107,17 +1151,18 @@ private fun SettingsContent( @Composable fun Debug() { + val debugTitle = stringResource(R.string.debug) + val debugHelp = stringResource(R.string.debug_help) Row( Modifier.fillMaxWidth().padding(end = 10.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Start ) { - val ctx = LocalContext.current - Text(text = stringResource(R.string.debug), + Text(text = debugTitle, modifier = Modifier.weight(1f) .clickable { - alertTitle.value = ctx.getString(R.string.debug) - alertMessage.value = ctx.getString(R.string.debug_help) + alertTitle.value = debugTitle + alertMessage.value = debugHelp showAlert.value = true }, fontSize = 18.sp @@ -1132,18 +1177,19 @@ private fun SettingsContent( @Composable fun SipTrace() { + val sipTraceTitle = stringResource(R.string.sip_trace) + val sipTraceHelp = stringResource(R.string.sip_trace_help) Row( Modifier.fillMaxWidth().padding(end = 10.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Start ) { - val ctx = LocalContext.current - Text(text = stringResource(R.string.sip_trace), + Text(text = sipTraceTitle, modifier = Modifier .weight(1f) .clickable { - alertTitle.value = ctx.getString(R.string.sip_trace) - alertMessage.value = ctx.getString(R.string.sip_trace_help) + alertTitle.value = sipTraceTitle + alertMessage.value = sipTraceHelp showAlert.value = true }, fontSize = 18.sp @@ -1158,18 +1204,21 @@ private fun SettingsContent( @Composable fun Reset(onRestartApp: () -> Unit) { + val resetConfigTitle = stringResource(R.string.reset_config) + val resetConfigHelp = stringResource(R.string.reset_config_help) + val resetConfigAlert = stringResource(R.string.reset_config_alert) + val resetButtonText = stringResource(R.string.reset) Row( Modifier.fillMaxWidth().padding(end = 10.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Start ) { - val ctx = LocalContext.current - Text(text = stringResource(R.string.reset_config), + Text(text = resetConfigTitle, modifier = Modifier .weight(1f) .clickable { - alertTitle.value = ctx.getString(R.string.reset_config) - alertMessage.value = ctx.getString(R.string.reset_config_help) + alertTitle.value = resetConfigTitle + alertMessage.value = resetConfigHelp showAlert.value = true }, fontSize = 18.sp @@ -1178,14 +1227,14 @@ private fun SettingsContent( Switch( checked = reset, onCheckedChange = { - dialogTitle.value = ctx.getString(R.string.confirmation) - dialogMessage.value = ctx.getString(R.string.reset_config_alert) - positiveText.value = ctx.getString(R.string.reset) + dialogTitle.value = confirmationText + dialogMessage.value = resetConfigAlert + positiveText.value = resetButtonText onPositiveClicked.value = { Config.reset() onRestartApp() } - negativeText.value = ctx.getString(R.string.cancel) + negativeText.value = cancelButtonText onNegativeClicked.value = { reset = false negativeText.value = "" @@ -1196,8 +1245,6 @@ private fun SettingsContent( } } - val ctx = LocalContext.current - if (Config.variable("auto_start") == "yes" && !isAppearOnTopPermissionGranted(LocalContext.current)) { Config.replaceVariable("auto_start", "no") @@ -1219,8 +1266,8 @@ private fun SettingsContent( verticalArrangement = Arrangement.spacedBy(8.dp), ) { item { StartAutomatically() } - item { ListenAddress() } item { AddressFamily() } + item { ListenAddress() } item { TransportProtocols() } item { DnsServers() } item { TlsCertificateFile(activity) } @@ -1229,7 +1276,7 @@ private fun SettingsContent( item { UserAgent() } item { AudioSettings(navController) } item { Contacts(activity) } - item { Ringtone(ctx) } + item { Ringtone() } item { BatteryOptimizations() } item { DarkTheme() } if (VERSION.SDK_INT >= 31) { @@ -1248,6 +1295,8 @@ private fun SettingsContent( private fun checkOnClick(ctx: Context, viewModel: SettingsViewModel): Boolean { + val noticeTitle = ctx.getString(R.string.notice) + if ((Config.variable("auto_start") == "yes") != viewModel.autoStart.value) { Config.replaceVariable( "auto_start", @@ -1259,7 +1308,7 @@ private fun checkOnClick(ctx: Context, viewModel: SettingsViewModel): Boolean { val listenAddr = viewModel.listenAddress.value.trim() if (listenAddr != Config.variable("sip_listen")) { if ((listenAddr != "") && !Utils.checkIpPort(listenAddr)) { - alertTitle.value = ctx.getString(R.string.notice) + alertTitle.value = noticeTitle alertMessage.value = "${ctx.getString(R.string.invalid_listen_address)}: $listenAddr" showAlert.value = true return false @@ -1279,7 +1328,7 @@ private fun checkOnClick(ctx: Context, viewModel: SettingsViewModel): Boolean { .lowercase(Locale.ROOT).replace(" ", "") if (transportProtocols != viewModel.oldTransportProtocols) { if (!checkTransportProtocols(transportProtocols)) { - alertTitle.value = ctx.getString(R.string.notice) + alertTitle.value = noticeTitle alertMessage.value = "${ctx.getString(R.string.invalid_transport_protocols)}: " + transportProtocols showAlert.value = true @@ -1296,7 +1345,7 @@ private fun checkOnClick(ctx: Context, viewModel: SettingsViewModel): Boolean { .lowercase(Locale.ROOT).replace(" ", "")) if (dnsServers != viewModel.oldDnsServers) { if (!checkDnsServers(dnsServers)) { - alertTitle.value = ctx.getString(R.string.notice) + alertTitle.value = noticeTitle alertMessage.value = "${ctx.getString(R.string.invalid_dns_servers)}: $dnsServers" showAlert.value = true return false @@ -1307,7 +1356,7 @@ private fun checkOnClick(ctx: Context, viewModel: SettingsViewModel): Boolean { Config.addVariable("dns_server", server) Config.replaceVariable("dyn_dns", "no") if (Api.net_use_nameserver(dnsServers) != 0) { - alertTitle.value = ctx.getString(R.string.notice) + alertTitle.value = noticeTitle alertMessage.value = "${ctx.getString(R.string.failed_to_set_dns_servers)}: $dnsServers" showAlert.value = true return false @@ -1330,7 +1379,7 @@ private fun checkOnClick(ctx: Context, viewModel: SettingsViewModel): Boolean { val userAgent = viewModel.userAgent.value.trim() if (userAgent != Config.variable("user_agent")) { if (userAgent != "" && !Utils.checkServerVal(userAgent)) { - alertTitle.value = ctx.getString(R.string.notice) + alertTitle.value = noticeTitle alertMessage.value = "${ctx.getString(R.string.invalid_user_agent)}: " + userAgent showAlert.value = true diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 2110871f..ec942ae5 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -159,6 +159,10 @@ Kertoo kuinka usein baresip lähettää REGISTER-sanomia. Arvon on oltava välillä 60-3600 (sekunttia). Virheellinen Rekisteröintitaajuus \'%1$s\' + Tarkista lähdeosoite + Merkitty, sisään tulevat SIP-sanomat sallitaan vain niistä + lähdeosoitteista, joihin REGISTER-sanomat lähetettiin. + Media NAT hallinta Valitsee media NAT hallintaprotokollan (vapaaehtoinen). Vaihtoehtoja ovat STUN (Session Traversal Utilities @@ -339,9 +343,10 @@ valittu, baresip käyttää sekä IPv4- että IPv6-osoitteita. Kuljetusprotokollat - Pilkulla toisistaan erotettu lista tuettuja SIP sanomien + Pilkulla toisistaan erotettu lista tuettuja SIP-sanomien kuljetusprotokollia. Jos jätetään tyhjäksi, oletusarvo on \'udp,tcp,tls,ws,wss\', joka - kaikki tuetut siirtoprotokollat. + sisältää kaikki tuetut kuljetusprotokollat. Listaa vain ne joita tarvitset. UDP-protokollan + käyttöä ei suositella turvallisuus- ja muista syistä. Virheellinen kuljetusprotokollalistas DNS-palvelimet diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b4d461e8..3fc8ae4d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -155,6 +155,10 @@ Tells how often (in seconds) baresip sends REGISTER requests. Valid values are from 60 to 3600. Invalid Registration Interval \'%1$s\' + Check Origin + If checked, inbound requests are allowed only from IP addresses + where register requests were sent. + Media NAT Traversal Selects media NAT traversal protocol (if any). Possible choices are STUN (Session Traversal Utilities for NAT, RFC 5389) and ICE (Interactive Connectivity @@ -327,7 +331,8 @@ Transport Protocols Comma separated list of supported SIP request/response transport protocols. If left empty, default value is \'udp,tcp,tls,ws,wss\' that includes - all supported transport protocols. + all supported transport protocols. List only the ones you need. Use of UDP is not + recommended for security and other reasons. Invalid Transport Protocols list DNS Servers