Improved settings dialog implementations
This commit is contained in:
@@ -63,7 +63,7 @@ import androidx.compose.ui.text.input.KeyboardType
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.tutpro.baresip.CustomElements.AlertDialog
|
||||||
import com.tutpro.baresip.CustomElements.Checkbox
|
import com.tutpro.baresip.CustomElements.Checkbox
|
||||||
import com.tutpro.baresip.CustomElements.verticalScrollbar
|
import com.tutpro.baresip.CustomElements.verticalScrollbar
|
||||||
import com.tutpro.baresip.Utils.copyInputStreamToFile
|
import com.tutpro.baresip.Utils.copyInputStreamToFile
|
||||||
@@ -116,6 +116,18 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
private var restart = false
|
private var restart = false
|
||||||
private var audioRestart = false
|
private var audioRestart = false
|
||||||
|
|
||||||
|
private val alertTitle = mutableStateOf("")
|
||||||
|
private val alertMessage = mutableStateOf("")
|
||||||
|
private val showAlert = mutableStateOf(false)
|
||||||
|
|
||||||
|
private val dialogTitle = mutableStateOf("")
|
||||||
|
private val dialogMessage = mutableStateOf("")
|
||||||
|
private val positiveText = mutableStateOf("")
|
||||||
|
private val onPositiveClicked = mutableStateOf({})
|
||||||
|
private val negativeText = mutableStateOf("")
|
||||||
|
private val onNegativeClicked = mutableStateOf({})
|
||||||
|
private val showDialog = mutableStateOf(false)
|
||||||
|
|
||||||
private val onBackPressedCallback = object : OnBackPressedCallback(true) {
|
private val onBackPressedCallback = object : OnBackPressedCallback(true) {
|
||||||
override fun handleOnBackPressed() {
|
override fun handleOnBackPressed() {
|
||||||
goBack()
|
goBack()
|
||||||
@@ -137,10 +149,9 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
save = true
|
save = true
|
||||||
restart = true
|
restart = true
|
||||||
} catch (e: Error) {
|
} catch (e: Error) {
|
||||||
Utils.alertView(
|
alertTitle.value = getString(R.string.error)
|
||||||
this, getString(R.string.error),
|
alertMessage.value = getString(R.string.read_cert_error) + ": " + e.message
|
||||||
getString(R.string.read_cert_error) + ": " + e.message
|
showAlert.value = true
|
||||||
)
|
|
||||||
newTlsCertificateFile = false
|
newTlsCertificateFile = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -162,10 +173,9 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
inputStream.close()
|
inputStream.close()
|
||||||
restart = true
|
restart = true
|
||||||
} catch (e: Error) {
|
} catch (e: Error) {
|
||||||
Utils.alertView(
|
alertTitle.value = getString(R.string.error)
|
||||||
this, getString(R.string.error),
|
alertMessage.value = getString(R.string.read_ca_certs_error) + ": " + e.message
|
||||||
getString(R.string.read_ca_certs_error) + ": " + e.message
|
showAlert.value = true
|
||||||
)
|
|
||||||
newCaFile = false
|
newCaFile = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -330,38 +340,62 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ConfigContent(ctx: Context, contentPadding: PaddingValues) {
|
fun ConfigContent(ctx: Context, contentPadding: PaddingValues) {
|
||||||
|
|
||||||
arrowTint = if (BaresipService.darkTheme.value)
|
arrowTint = if (BaresipService.darkTheme.value)
|
||||||
LocalCustomColors.current.grayLight
|
LocalCustomColors.current.grayLight
|
||||||
else
|
else
|
||||||
LocalCustomColors.current.black
|
LocalCustomColors.current.black
|
||||||
|
|
||||||
|
if (showAlert.value) {
|
||||||
|
AlertDialog(
|
||||||
|
showDialog = showAlert,
|
||||||
|
title = alertTitle.value,
|
||||||
|
message = alertMessage.value,
|
||||||
|
positiveButtonText = stringResource(R.string.ok),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (showDialog.value)
|
||||||
|
AlertDialog(
|
||||||
|
showDialog = showDialog,
|
||||||
|
title = alertTitle.value,
|
||||||
|
message = alertMessage.value,
|
||||||
|
positiveButtonText = positiveText.value,
|
||||||
|
onPositiveClicked = onPositiveClicked.value,
|
||||||
|
negativeButtonText = negativeText.value,
|
||||||
|
onNegativeClicked = onNegativeClicked.value,
|
||||||
|
)
|
||||||
|
|
||||||
val scrollState = rememberScrollState()
|
val scrollState = rememberScrollState()
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.imePadding()
|
.imePadding()
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(contentPadding)
|
.padding(contentPadding)
|
||||||
.padding(start = 16.dp, end = 4.dp, top = 8.dp, bottom = 8.dp)
|
.padding(start = 16.dp, end = 4.dp, top = 16.dp, bottom = 8.dp)
|
||||||
.verticalScrollbar(scrollState)
|
.verticalScrollbar(scrollState)
|
||||||
.verticalScroll(state = scrollState),
|
.verticalScroll(state = scrollState),
|
||||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||||
) {
|
) {
|
||||||
StartAutomatically(ctx)
|
StartAutomatically(ctx)
|
||||||
ListenAddress(ctx)
|
ListenAddress()
|
||||||
AddressFamily(ctx)
|
AddressFamily()
|
||||||
DnsServers(ctx)
|
DnsServers()
|
||||||
TlsCertificateFile(ctx)
|
TlsCertificateFile(ctx)
|
||||||
VerifyServer(ctx)
|
VerifyServer()
|
||||||
CaFile(ctx)
|
CaFile(ctx)
|
||||||
UserAgent(ctx)
|
UserAgent()
|
||||||
AudioSettings(ctx)
|
AudioSettings(ctx)
|
||||||
BatteryOptimizations(ctx)
|
BatteryOptimizations()
|
||||||
if (Build.VERSION.SDK_INT >= 29)
|
if (Build.VERSION.SDK_INT >= 29)
|
||||||
DefaultDialer(ctx)
|
DefaultDialer()
|
||||||
Contacts(ctx)
|
Contacts(ctx)
|
||||||
DarkTheme(ctx)
|
DarkTheme()
|
||||||
Debug(ctx)
|
Debug()
|
||||||
SipTrace(ctx)
|
SipTrace()
|
||||||
Reset(ctx)
|
Reset()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -376,10 +410,9 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
.clickable {
|
.clickable {
|
||||||
Utils.alertView(
|
alertTitle.value = getString(R.string.start_automatically)
|
||||||
ctx, getString(R.string.start_automatically),
|
alertMessage.value = getString(R.string.start_automatically_help)
|
||||||
getString(R.string.start_automatically_help)
|
showAlert.value = true
|
||||||
)
|
|
||||||
},
|
},
|
||||||
color = LocalCustomColors.current.itemText,
|
color = LocalCustomColors.current.itemText,
|
||||||
fontSize = 18.sp)
|
fontSize = 18.sp)
|
||||||
@@ -390,28 +423,19 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
onCheckedChange = {
|
onCheckedChange = {
|
||||||
if (it) {
|
if (it) {
|
||||||
if (!isAppearOnTopPermissionGranted(ctx)) {
|
if (!isAppearOnTopPermissionGranted(ctx)) {
|
||||||
with(
|
dialogTitle.value = getString(R.string.notice)
|
||||||
MaterialAlertDialogBuilder(
|
dialogMessage.value = getString(R.string.appear_on_top_permission)
|
||||||
ctx,
|
positiveText.value = getString(R.string.ok)
|
||||||
R.style.AlertDialogTheme
|
onPositiveClicked.value = {
|
||||||
)
|
managingOverlayPermission = true
|
||||||
) {
|
val intent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION)
|
||||||
setTitle(getText(R.string.notice))
|
startActivity(intent)
|
||||||
setMessage(getText(R.string.appear_on_top_permission))
|
|
||||||
setPositiveButton(getText(R.string.ok)) { dialog, _ ->
|
|
||||||
dialog.dismiss()
|
|
||||||
managingOverlayPermission = true
|
|
||||||
val intent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION)
|
|
||||||
startActivity(intent)
|
|
||||||
}
|
|
||||||
setNegativeButton(getText(R.string.cancel)) { dialog, _ ->
|
|
||||||
dialog.dismiss()
|
|
||||||
}
|
|
||||||
val dialog = this.create()
|
|
||||||
dialog.setCancelable(false)
|
|
||||||
dialog.setCanceledOnTouchOutside(false)
|
|
||||||
dialog.show()
|
|
||||||
}
|
}
|
||||||
|
negativeText.value = getString(R.string.cancel)
|
||||||
|
onNegativeClicked.value = {
|
||||||
|
negativeText.value = ""
|
||||||
|
}
|
||||||
|
showDialog.value = true
|
||||||
startAutomatically = false
|
startAutomatically = false
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -426,7 +450,7 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun ListenAddress(ctx: Context) {
|
private fun ListenAddress() {
|
||||||
Row(
|
Row(
|
||||||
Modifier
|
Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
@@ -446,10 +470,9 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.clickable {
|
.clickable {
|
||||||
Utils.alertView(
|
alertTitle.value = getString(R.string.listen_address)
|
||||||
ctx, getString(R.string.listen_address),
|
alertMessage.value = getString(R.string.listen_address_help)
|
||||||
getString(R.string.listen_address_help)
|
showAlert.value = true
|
||||||
)
|
|
||||||
},
|
},
|
||||||
textStyle = androidx.compose.ui.text.TextStyle(
|
textStyle = androidx.compose.ui.text.TextStyle(
|
||||||
fontSize = 18.sp, color = LocalCustomColors.current.itemText),
|
fontSize = 18.sp, color = LocalCustomColors.current.itemText),
|
||||||
@@ -460,7 +483,7 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun AddressFamily(ctx: Context) {
|
private fun AddressFamily() {
|
||||||
Row(
|
Row(
|
||||||
Modifier
|
Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
@@ -472,10 +495,9 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
.clickable {
|
.clickable {
|
||||||
Utils.alertView(
|
alertTitle.value = getString(R.string.address_family)
|
||||||
ctx, getString(R.string.address_family),
|
alertMessage.value = getString(R.string.address_family_help)
|
||||||
getString(R.string.address_family_help)
|
showAlert.value = true
|
||||||
)
|
|
||||||
},
|
},
|
||||||
color = LocalCustomColors.current.itemText,
|
color = LocalCustomColors.current.itemText,
|
||||||
fontSize = 18.sp)
|
fontSize = 18.sp)
|
||||||
@@ -526,7 +548,7 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun DnsServers(ctx: Context) {
|
private fun DnsServers() {
|
||||||
Row(
|
Row(
|
||||||
Modifier
|
Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
@@ -545,10 +567,9 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.clickable {
|
.clickable {
|
||||||
Utils.alertView(
|
alertTitle.value = getString(R.string.dns_servers)
|
||||||
ctx, getString(R.string.dns_servers),
|
alertMessage.value = getString(R.string.dns_servers_help)
|
||||||
getString(R.string.dns_servers_help)
|
showAlert.value = true
|
||||||
)
|
|
||||||
},
|
},
|
||||||
textStyle = androidx.compose.ui.text.TextStyle(
|
textStyle = androidx.compose.ui.text.TextStyle(
|
||||||
fontSize = 18.sp, color = LocalCustomColors.current.itemText),
|
fontSize = 18.sp, color = LocalCustomColors.current.itemText),
|
||||||
@@ -560,6 +581,7 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun TlsCertificateFile(ctx: Context) {
|
private fun TlsCertificateFile(ctx: Context) {
|
||||||
|
val showAlertDialog = remember { mutableStateOf(false) }
|
||||||
Row(
|
Row(
|
||||||
Modifier.fillMaxWidth(),
|
Modifier.fillMaxWidth(),
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
@@ -569,10 +591,9 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
.clickable {
|
.clickable {
|
||||||
Utils.alertView(
|
alertTitle.value = getString(R.string.tls_certificate_file)
|
||||||
ctx, getString(R.string.tls_certificate_file),
|
alertMessage.value = getString(R.string.tls_certificate_file_help)
|
||||||
getString(R.string.tls_certificate_file_help)
|
showAlert.value = true
|
||||||
)
|
|
||||||
},
|
},
|
||||||
color = LocalCustomColors.current.itemText,
|
color = LocalCustomColors.current.itemText,
|
||||||
fontSize = 18.sp)
|
fontSize = 18.sp)
|
||||||
@@ -594,10 +615,9 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
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) {
|
||||||
Utils.alertView(
|
alertTitle.value = getString(R.string.error)
|
||||||
ctx, getString(R.string.error),
|
alertMessage.value = getString(R.string.read_cert_error)
|
||||||
getString(R.string.read_cert_error)
|
showAlert.value = true
|
||||||
)
|
|
||||||
return@Checkbox
|
return@Checkbox
|
||||||
}
|
}
|
||||||
val certPath = BaresipService.filesPath + "/cert.pem"
|
val certPath = BaresipService.filesPath + "/cert.pem"
|
||||||
@@ -607,10 +627,9 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
save = true
|
save = true
|
||||||
restart = true
|
restart = true
|
||||||
}
|
}
|
||||||
shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE) ->
|
shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE) -> {
|
||||||
Utils.alertView(ctx, getString(R.string.notice), getString(R.string.no_android_contacts)) {
|
showAlertDialog.value = true
|
||||||
requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
|
}
|
||||||
}
|
|
||||||
else ->
|
else ->
|
||||||
requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
|
requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||||
}
|
}
|
||||||
@@ -625,10 +644,20 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
if (showAlertDialog.value)
|
||||||
|
AlertDialog(
|
||||||
|
showDialog = showAlertDialog,
|
||||||
|
title = getString(R.string.notice),
|
||||||
|
message = getString(R.string.no_read_permission),
|
||||||
|
positiveButtonText = getString(R.string.ok),
|
||||||
|
onPositiveClicked = { requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE) },
|
||||||
|
negativeButtonText = "",
|
||||||
|
onNegativeClicked = {},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun VerifyServer(ctx: Context) {
|
private fun VerifyServer() {
|
||||||
Row(
|
Row(
|
||||||
Modifier.fillMaxWidth(),
|
Modifier.fillMaxWidth(),
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
@@ -638,10 +667,9 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
.clickable {
|
.clickable {
|
||||||
Utils.alertView(
|
alertTitle.value = getString(R.string.verify_server)
|
||||||
ctx, getString(R.string.verify_server),
|
alertMessage.value = getString(R.string.verify_server_help)
|
||||||
getString(R.string.verify_server_help)
|
showAlert.value = true
|
||||||
)
|
|
||||||
},
|
},
|
||||||
color = LocalCustomColors.current.itemText,
|
color = LocalCustomColors.current.itemText,
|
||||||
fontSize = 18.sp)
|
fontSize = 18.sp)
|
||||||
@@ -667,10 +695,9 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
.clickable {
|
.clickable {
|
||||||
Utils.alertView(
|
alertTitle.value = getString(R.string.tls_ca_file)
|
||||||
ctx, getString(R.string.tls_ca_file),
|
alertMessage.value = getString(R.string.tls_ca_file_help)
|
||||||
getString(R.string.tls_certificate_file_help)
|
showAlert.value = true
|
||||||
)
|
|
||||||
},
|
},
|
||||||
color = LocalCustomColors.current.itemText,
|
color = LocalCustomColors.current.itemText,
|
||||||
fontSize = 18.sp)
|
fontSize = 18.sp)
|
||||||
@@ -691,24 +718,33 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
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) {
|
||||||
Utils.alertView(ctx, getString(R.string.error), getString(R.string.read_ca_certs_error))
|
alertTitle.value = getString(R.string.error)
|
||||||
|
alertMessage.value = getString(R.string.read_ca_certs_error)
|
||||||
|
showAlert.value = true
|
||||||
return@Checkbox
|
return@Checkbox
|
||||||
}
|
}
|
||||||
caCertsFile.writeBytes(content)
|
caCertsFile.writeBytes(content)
|
||||||
caFile = true
|
caFile = true
|
||||||
restart = true
|
restart = true
|
||||||
}
|
}
|
||||||
shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE) ->
|
shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE) -> {
|
||||||
Utils.alertView(ctx, getString(R.string.notice), getString(R.string.no_android_contacts)) {
|
dialogTitle.value = getString(R.string.notice)
|
||||||
|
dialogMessage.value = getString(R.string.no_read_permission)
|
||||||
|
positiveText.value = getString(R.string.ok)
|
||||||
|
onPositiveClicked.value = {
|
||||||
requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
|
requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||||
}
|
}
|
||||||
|
negativeText.value = ""
|
||||||
|
showDialog.value = true
|
||||||
|
}
|
||||||
else ->
|
else ->
|
||||||
requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
|
requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
Utils.selectInputFile(caCertsRequest)
|
|
||||||
}
|
}
|
||||||
} else {
|
else
|
||||||
|
Utils.selectInputFile(caCertsRequest)
|
||||||
|
}
|
||||||
|
else {
|
||||||
if (caCertsFile.exists())
|
if (caCertsFile.exists())
|
||||||
caCertsFile.delete()
|
caCertsFile.delete()
|
||||||
restart = true
|
restart = true
|
||||||
@@ -719,7 +755,7 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun UserAgent(ctx: Context) {
|
private fun UserAgent() {
|
||||||
Row(
|
Row(
|
||||||
Modifier
|
Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
@@ -739,10 +775,9 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.clickable {
|
.clickable {
|
||||||
Utils.alertView(
|
alertTitle.value = getString(R.string.user_agent)
|
||||||
ctx, getString(R.string.user_agent),
|
alertMessage.value = getString(R.string.user_agent_help)
|
||||||
getString(R.string.user_agent_help)
|
showAlert.value = true
|
||||||
)
|
|
||||||
},
|
},
|
||||||
textStyle = androidx.compose.ui.text.TextStyle(
|
textStyle = androidx.compose.ui.text.TextStyle(
|
||||||
fontSize = 18.sp, color = LocalCustomColors.current.itemText),
|
fontSize = 18.sp, color = LocalCustomColors.current.itemText),
|
||||||
@@ -776,7 +811,7 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun BatteryOptimizations(ctx: Context) {
|
private fun BatteryOptimizations() {
|
||||||
Row(
|
Row(
|
||||||
Modifier.fillMaxWidth(),
|
Modifier.fillMaxWidth(),
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
@@ -786,10 +821,9 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
.clickable {
|
.clickable {
|
||||||
Utils.alertView(
|
alertTitle.value = getString(R.string.battery_optimizations)
|
||||||
ctx, getString(R.string.battery_optimizations),
|
alertMessage.value = getString(R.string.battery_optimizations_help)
|
||||||
getString(R.string.battery_optimizations_help)
|
showAlert.value = true
|
||||||
)
|
|
||||||
},
|
},
|
||||||
color = LocalCustomColors.current.itemText,
|
color = LocalCustomColors.current.itemText,
|
||||||
fontSize = 18.sp)
|
fontSize = 18.sp)
|
||||||
@@ -811,7 +845,7 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
|
|
||||||
@RequiresApi(29)
|
@RequiresApi(29)
|
||||||
@Composable
|
@Composable
|
||||||
private fun DefaultDialer(ctx: Context) {
|
private fun DefaultDialer() {
|
||||||
Row(
|
Row(
|
||||||
Modifier.fillMaxWidth(),
|
Modifier.fillMaxWidth(),
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
@@ -821,10 +855,9 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
.clickable {
|
.clickable {
|
||||||
Utils.alertView(
|
alertTitle.value = getString(R.string.default_phone_app)
|
||||||
ctx, getString(R.string.default_phone_app),
|
alertMessage.value = getString(R.string.default_phone_app_help)
|
||||||
getString(R.string.default_phone_app_help)
|
showAlert.value = true
|
||||||
)
|
|
||||||
},
|
},
|
||||||
color = LocalCustomColors.current.itemText,
|
color = LocalCustomColors.current.itemText,
|
||||||
fontSize = 18.sp)
|
fontSize = 18.sp)
|
||||||
@@ -835,9 +868,11 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
defaultDialer = it
|
defaultDialer = it
|
||||||
newDefaultDialer = defaultDialer
|
newDefaultDialer = defaultDialer
|
||||||
if (it) {
|
if (it) {
|
||||||
if (!roleManager.isRoleAvailable(RoleManager.ROLE_DIALER))
|
if (!roleManager.isRoleAvailable(RoleManager.ROLE_DIALER)) {
|
||||||
Utils.alertView(ctx, getString(R.string.notice),
|
alertTitle.value = getString(R.string.alert)
|
||||||
getString(R.string.dialer_role_not_available))
|
alertMessage.value = getString(R.string.dialer_role_not_available)
|
||||||
|
showAlert.value = true
|
||||||
|
}
|
||||||
else
|
else
|
||||||
if (!roleManager.isRoleHeld(RoleManager.ROLE_DIALER))
|
if (!roleManager.isRoleHeld(RoleManager.ROLE_DIALER))
|
||||||
dialerRoleRequest.launch(roleManager.createRequestRoleIntent(RoleManager.ROLE_DIALER))
|
dialerRoleRequest.launch(roleManager.createRequestRoleIntent(RoleManager.ROLE_DIALER))
|
||||||
@@ -855,6 +890,7 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun Contacts(ctx: Context) {
|
private fun Contacts(ctx: Context) {
|
||||||
|
val showAlertDialog = remember { mutableStateOf(false) }
|
||||||
Row(
|
Row(
|
||||||
Modifier
|
Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
@@ -866,10 +902,9 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
.clickable {
|
.clickable {
|
||||||
Utils.alertView(
|
alertTitle.value = getString(R.string.contacts)
|
||||||
ctx, getString(R.string.contacts),
|
alertMessage.value = getString(R.string.contacts_help)
|
||||||
getString(R.string.contacts_help)
|
showAlert.value = true
|
||||||
)
|
|
||||||
},
|
},
|
||||||
color = LocalCustomColors.current.itemText,
|
color = LocalCustomColors.current.itemText,
|
||||||
fontSize = 18.sp)
|
fontSize = 18.sp)
|
||||||
@@ -908,24 +943,42 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
onClick = {
|
onClick = {
|
||||||
isDropDownExpanded.value = false
|
isDropDownExpanded.value = false
|
||||||
val mode = contactValues[index]
|
val mode = contactValues[index]
|
||||||
if (mode != "baresip" && !Utils.checkPermissions(applicationContext, contactsPermissions))
|
if (mode != "baresip" && !Utils.checkPermissions(applicationContext, contactsPermissions)) {
|
||||||
with(MaterialAlertDialogBuilder(ctx, R.style.AlertDialogTheme)) {
|
dialogTitle.value = getString(R.string.consent_request)
|
||||||
setTitle(getText(R.string.consent_request))
|
dialogMessage.value = getString(R.string.contacts_consent)
|
||||||
setMessage(getText(R.string.contacts_consent))
|
positiveText.value = getString(R.string.accept)
|
||||||
setPositiveButton(getText(R.string.accept)) { dialog, _ ->
|
onPositiveClicked.value = {
|
||||||
dialog.dismiss()
|
showDialog.value = false
|
||||||
newContactsMode = mode
|
newContactsMode = mode
|
||||||
askForContactsPermission(ctx)
|
if (ContextCompat.checkSelfPermission(
|
||||||
|
ctx,
|
||||||
|
Manifest.permission.READ_CONTACTS
|
||||||
|
) == PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(
|
||||||
|
ctx,
|
||||||
|
Manifest.permission.WRITE_CONTACTS
|
||||||
|
) == PackageManager.PERMISSION_GRANTED
|
||||||
|
) {
|
||||||
|
Log.d(TAG, "Contacts permissions already granted")
|
||||||
|
} else {
|
||||||
|
if (shouldShowRequestPermissionRationale(Manifest.permission.READ_CONTACTS) ||
|
||||||
|
shouldShowRequestPermissionRationale(Manifest.permission.WRITE_CONTACTS))
|
||||||
|
showAlertDialog.value = true
|
||||||
|
else
|
||||||
|
requestPermissionsLauncher.launch(
|
||||||
|
arrayOf(
|
||||||
|
Manifest.permission.READ_CONTACTS,
|
||||||
|
Manifest.permission.WRITE_CONTACTS
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
setNegativeButton(getText(R.string.deny)) { dialog, _ ->
|
|
||||||
itemPosition.intValue = contactValues.indexOf(oldContactsMode)
|
|
||||||
dialog.dismiss()
|
|
||||||
}
|
|
||||||
val dialog = this.create()
|
|
||||||
dialog.setCancelable(false)
|
|
||||||
dialog.setCanceledOnTouchOutside(false)
|
|
||||||
dialog.show()
|
|
||||||
}
|
}
|
||||||
|
negativeText.value = getString(R.string.deny)
|
||||||
|
onNegativeClicked.value = {
|
||||||
|
itemPosition.intValue = contactValues.indexOf(oldContactsMode)
|
||||||
|
negativeText.value = ""
|
||||||
|
}
|
||||||
|
showDialog.value = true
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
itemPosition.intValue = index
|
itemPosition.intValue = index
|
||||||
newContactsMode = contactValues[index]
|
newContactsMode = contactValues[index]
|
||||||
@@ -939,11 +992,26 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (showAlertDialog.value)
|
||||||
|
AlertDialog(
|
||||||
|
showDialog = showAlertDialog,
|
||||||
|
title = getString(R.string.notice),
|
||||||
|
message = getString(R.string.no_android_contacts),
|
||||||
|
positiveButtonText = getString(R.string.ok),
|
||||||
|
onPositiveClicked = { requestPermissionsLauncher.launch(
|
||||||
|
arrayOf(
|
||||||
|
Manifest.permission.READ_CONTACTS,
|
||||||
|
Manifest.permission.WRITE_CONTACTS
|
||||||
|
)
|
||||||
|
)},
|
||||||
|
negativeButtonText = "",
|
||||||
|
onNegativeClicked = {},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun DarkTheme(ctx: Context) {
|
private fun DarkTheme() {
|
||||||
Row(
|
Row(
|
||||||
Modifier.fillMaxWidth(),
|
Modifier.fillMaxWidth(),
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
@@ -953,10 +1021,9 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
.clickable {
|
.clickable {
|
||||||
Utils.alertView(
|
alertTitle.value = getString(R.string.dark_theme)
|
||||||
ctx, getString(R.string.dark_theme),
|
alertMessage.value = getString(R.string.dark_theme_help)
|
||||||
getString(R.string.dark_theme_help)
|
showAlert.value = true
|
||||||
)
|
|
||||||
},
|
},
|
||||||
color = LocalCustomColors.current.itemText,
|
color = LocalCustomColors.current.itemText,
|
||||||
fontSize = 18.sp)
|
fontSize = 18.sp)
|
||||||
@@ -972,7 +1039,7 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun Debug(ctx: Context) {
|
private fun Debug() {
|
||||||
Row(
|
Row(
|
||||||
Modifier.fillMaxWidth(),
|
Modifier.fillMaxWidth(),
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
@@ -982,10 +1049,9 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
.clickable {
|
.clickable {
|
||||||
Utils.alertView(
|
alertTitle.value = getString(R.string.debug)
|
||||||
ctx, getString(R.string.debug),
|
alertMessage.value = getString(R.string.debug_help)
|
||||||
getString(R.string.debug_help)
|
showAlert.value = true
|
||||||
)
|
|
||||||
},
|
},
|
||||||
color = LocalCustomColors.current.itemText,
|
color = LocalCustomColors.current.itemText,
|
||||||
fontSize = 18.sp)
|
fontSize = 18.sp)
|
||||||
@@ -1001,7 +1067,7 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun SipTrace(ctx: Context) {
|
private fun SipTrace() {
|
||||||
Row(
|
Row(
|
||||||
Modifier.fillMaxWidth(),
|
Modifier.fillMaxWidth(),
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
@@ -1011,10 +1077,9 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
.clickable {
|
.clickable {
|
||||||
Utils.alertView(
|
alertTitle.value = getString(R.string.sip_trace)
|
||||||
ctx, getString(R.string.sip_trace),
|
alertMessage.value = getString(R.string.sip_trace_help)
|
||||||
getString(R.string.sip_trace_help)
|
showAlert.value = true
|
||||||
)
|
|
||||||
},
|
},
|
||||||
color = LocalCustomColors.current.itemText,
|
color = LocalCustomColors.current.itemText,
|
||||||
fontSize = 18.sp)
|
fontSize = 18.sp)
|
||||||
@@ -1030,7 +1095,7 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun Reset(ctx: Context) {
|
private fun Reset() {
|
||||||
Row(
|
Row(
|
||||||
Modifier.fillMaxWidth(),
|
Modifier.fillMaxWidth(),
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
@@ -1040,10 +1105,9 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
.clickable {
|
.clickable {
|
||||||
Utils.alertView(
|
alertTitle.value = getString(R.string.reset_config)
|
||||||
ctx, getString(R.string.reset_config),
|
alertMessage.value = getString(R.string.reset_config_help)
|
||||||
getString(R.string.reset_config_help)
|
showAlert.value = true
|
||||||
)
|
|
||||||
},
|
},
|
||||||
color = LocalCustomColors.current.itemText,
|
color = LocalCustomColors.current.itemText,
|
||||||
fontSize = 18.sp)
|
fontSize = 18.sp)
|
||||||
@@ -1051,23 +1115,21 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
Checkbox(
|
Checkbox(
|
||||||
checked = reset,
|
checked = reset,
|
||||||
onCheckedChange = {
|
onCheckedChange = {
|
||||||
with(MaterialAlertDialogBuilder(ctx,
|
dialogTitle.value = getString(R.string.confirmation)
|
||||||
R.style.AlertDialogTheme)) {
|
dialogMessage.value = getString(R.string.reset_config_alert)
|
||||||
setTitle(R.string.confirmation)
|
positiveText.value = getString(R.string.reset)
|
||||||
setMessage(getString(R.string.reset_config_alert))
|
onPositiveClicked.value = {
|
||||||
setPositiveButton(getText(R.string.reset)) { dialog, _ ->
|
Config.reset()
|
||||||
Config.reset()
|
save = false
|
||||||
save = false
|
restart = true
|
||||||
restart = true
|
done()
|
||||||
done()
|
|
||||||
dialog.dismiss()
|
|
||||||
}
|
|
||||||
setNeutralButton(getText(R.string.cancel)) { dialog, _ ->
|
|
||||||
reset = false
|
|
||||||
dialog.dismiss()
|
|
||||||
}
|
|
||||||
show()
|
|
||||||
}
|
}
|
||||||
|
negativeText.value = getString(R.string.cancel)
|
||||||
|
onNegativeClicked.value = {
|
||||||
|
reset = false
|
||||||
|
negativeText.value = ""
|
||||||
|
}
|
||||||
|
showDialog.value = true
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -1087,8 +1149,9 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
val listenAddr = newListenAddr.trim()
|
val listenAddr = newListenAddr.trim()
|
||||||
if (listenAddr != oldListenAddr) {
|
if (listenAddr != oldListenAddr) {
|
||||||
if ((listenAddr != "") && !Utils.checkIpPort(listenAddr)) {
|
if ((listenAddr != "") && !Utils.checkIpPort(listenAddr)) {
|
||||||
Utils.alertView(this, getString(R.string.notice),
|
alertTitle.value = getString(R.string.notice)
|
||||||
"${getString(R.string.invalid_listen_address)}: $listenAddr")
|
alertMessage.value = "${getString(R.string.invalid_listen_address)}: $listenAddr"
|
||||||
|
showAlert.value = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
Config.replaceVariable("sip_listen", listenAddr)
|
Config.replaceVariable("sip_listen", listenAddr)
|
||||||
@@ -1107,8 +1170,9 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
dnsServers = addMissingPorts(dnsServers)
|
dnsServers = addMissingPorts(dnsServers)
|
||||||
if (dnsServers != oldDnsServers.replace(" ", "")) {
|
if (dnsServers != oldDnsServers.replace(" ", "")) {
|
||||||
if (!checkDnsServers(dnsServers)) {
|
if (!checkDnsServers(dnsServers)) {
|
||||||
Utils.alertView(this, getString(R.string.notice),
|
alertTitle.value = getString(R.string.notice)
|
||||||
"${getString(R.string.invalid_dns_servers)}: $dnsServers")
|
alertMessage.value = "${getString(R.string.invalid_dns_servers)}: $dnsServers"
|
||||||
|
showAlert.value = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
Config.removeVariable("dns_server")
|
Config.removeVariable("dns_server")
|
||||||
@@ -1117,8 +1181,9 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
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) {
|
||||||
Utils.alertView(this, getString(R.string.error),
|
alertTitle.value = getString(R.string.notice)
|
||||||
"${getString(R.string.failed_to_set_dns_servers)}: $dnsServers")
|
alertMessage.value = "${getString(R.string.failed_to_set_dns_servers)}: $dnsServers"
|
||||||
|
showAlert.value = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -1139,8 +1204,9 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
newUserAgent = newUserAgent.trim()
|
newUserAgent = newUserAgent.trim()
|
||||||
if (newUserAgent != oldUserAgent) {
|
if (newUserAgent != oldUserAgent) {
|
||||||
if ((newUserAgent != "") && !Utils.checkServerVal(newUserAgent)) {
|
if ((newUserAgent != "") && !Utils.checkServerVal(newUserAgent)) {
|
||||||
Utils.alertView(this, getString(R.string.notice),
|
alertTitle.value = getString(R.string.notice)
|
||||||
"${getString(R.string.invalid_user_agent)}: $newUserAgent")
|
alertMessage.value = "${getString(R.string.invalid_user_agent)}: $newUserAgent"
|
||||||
|
showAlert.value = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (newUserAgent != "")
|
if (newUserAgent != "")
|
||||||
@@ -1219,38 +1285,6 @@ class ConfigActivity : ComponentActivity() {
|
|||||||
registerForActivityResult(ActivityResultContracts.RequestPermission()) {}
|
registerForActivityResult(ActivityResultContracts.RequestPermission()) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun askForContactsPermission(ctx: Context) {
|
|
||||||
if (ContextCompat.checkSelfPermission(
|
|
||||||
this,
|
|
||||||
Manifest.permission.READ_CONTACTS
|
|
||||||
) == PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(
|
|
||||||
this,
|
|
||||||
Manifest.permission.WRITE_CONTACTS
|
|
||||||
) == PackageManager.PERMISSION_GRANTED
|
|
||||||
) {
|
|
||||||
Log.d(TAG, "Contacts permissions already granted")
|
|
||||||
} else {
|
|
||||||
if (shouldShowRequestPermissionRationale(Manifest.permission.READ_CONTACTS) ||
|
|
||||||
shouldShowRequestPermissionRationale(Manifest.permission.WRITE_CONTACTS)) {
|
|
||||||
Utils.alertView(ctx, getString(R.string.notice), getString(R.string.no_android_contacts)
|
|
||||||
) {
|
|
||||||
requestPermissionsLauncher.launch(
|
|
||||||
arrayOf(
|
|
||||||
Manifest.permission.READ_CONTACTS,
|
|
||||||
Manifest.permission.WRITE_CONTACTS
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
requestPermissionsLauncher.launch(
|
|
||||||
arrayOf(
|
|
||||||
Manifest.permission.READ_CONTACTS,
|
|
||||||
Manifest.permission.WRITE_CONTACTS
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun isAppearOnTopPermissionGranted(ctx: Context): Boolean {
|
private fun isAppearOnTopPermissionGranted(ctx: Context): Boolean {
|
||||||
return Settings.canDrawOverlays(ctx)
|
return Settings.canDrawOverlays(ctx)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user