Added Check Origin account setting

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