From 861693a19778db984907836a512b25be2ecb1b01 Mon Sep 17 00:00:00 2001 From: Juha Heinanen Date: Wed, 10 Nov 2021 10:37:15 +0200 Subject: [PATCH] More permissions request improvements --- app/src/main/AndroidManifest.xml | 1 - .../com/tutpro/baresip/ConfigActivity.kt | 128 +++++------ .../kotlin/com/tutpro/baresip/Constants.kt | 9 +- .../com/tutpro/baresip/ContactActivity.kt | 61 ++--- .../kotlin/com/tutpro/baresip/MainActivity.kt | 209 +++++++++--------- .../main/kotlin/com/tutpro/baresip/Utils.kt | 2 +- app/src/main/res/values/strings.xml | 10 +- 7 files changed, 204 insertions(+), 216 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 39742349..f32ee449 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -10,7 +10,6 @@ - diff --git a/app/src/main/kotlin/com/tutpro/baresip/ConfigActivity.kt b/app/src/main/kotlin/com/tutpro/baresip/ConfigActivity.kt index fd22e672..81229007 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/ConfigActivity.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/ConfigActivity.kt @@ -123,43 +123,45 @@ class ConfigActivity : AppCompatActivity() { if (isChecked) { if (Build.VERSION.SDK_INT < 29) { certificateFile.isChecked = false - if (ContextCompat.checkSelfPermission( + when { + ContextCompat.checkSelfPermission( this, Manifest.permission.READ_EXTERNAL_STORAGE - ) == PackageManager.PERMISSION_GRANTED - ) { - Log.d(TAG, "Read External Storage permission granted") - val downloadsPath = Utils.downloadsPath("cert.pem") - val content = Utils.getFileContents(downloadsPath) - if (content == null) { - Utils.alertView( - this, getString(R.string.error), - getString(R.string.read_cert_error) - ) - return@setOnCheckedChangeListener + ) == PackageManager.PERMISSION_GRANTED -> { + Log.d(TAG, "Read External Storage permission granted") + val downloadsPath = Utils.downloadsPath("cert.pem") + val content = Utils.getFileContents(downloadsPath) + if (content == null) { + Utils.alertView( + this, getString(R.string.error), + getString(R.string.read_cert_error) + ) + return@setOnCheckedChangeListener + } + val filesPath = BaresipService.filesPath + "/cert.pem" + Utils.putFileContents(filesPath, content) + Config.removeVariable("sip_certificate") + Config.addLine("sip_certificate $filesPath") + certificateFile.isChecked = true + save = true + restart = true } - val filesPath = BaresipService.filesPath + "/cert.pem" - Utils.putFileContents(filesPath, content) - Config.removeVariable("sip_certificate") - Config.addLine("sip_certificate $filesPath") - certificateFile.isChecked = true - save = true - restart = true - } else if (ActivityCompat.shouldShowRequestPermissionRationale( + ActivityCompat.shouldShowRequestPermissionRationale( this, Manifest.permission.READ_EXTERNAL_STORAGE - ) - ) { - layout.showSnackBar( - binding.root, - getString(R.string.no_restore), - Snackbar.LENGTH_INDEFINITE, - getString(R.string.ok) - ) { + ) -> { + layout.showSnackBar( + binding.root, + getString(R.string.no_restore), + Snackbar.LENGTH_INDEFINITE, + getString(R.string.ok) + ) { + requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE) + } + } + else -> { requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE) } - } else { - requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE) } } else { Utils.selectInputFile(certificateRequest) @@ -211,43 +213,45 @@ class ConfigActivity : AppCompatActivity() { if (isChecked) { if (Build.VERSION.SDK_INT < 29) { caFile.isChecked = false - if (ContextCompat.checkSelfPermission( + when { + ContextCompat.checkSelfPermission( this, Manifest.permission.READ_EXTERNAL_STORAGE - ) == PackageManager.PERMISSION_GRANTED - ) { - Log.d(TAG, "Read External Storage permission granted") - val downloadsPath = Utils.downloadsPath("ca_certs.crt") - val content = Utils.getFileContents(downloadsPath) - if (content == null) { - Utils.alertView( - this, getString(R.string.error), - getString(R.string.read_ca_certs_error) - ) - return@setOnCheckedChangeListener + ) == PackageManager.PERMISSION_GRANTED -> { + Log.d(TAG, "Read External Storage permission granted") + val downloadsPath = Utils.downloadsPath("ca_certs.crt") + val content = Utils.getFileContents(downloadsPath) + if (content == null) { + Utils.alertView( + this, getString(R.string.error), + getString(R.string.read_ca_certs_error) + ) + return@setOnCheckedChangeListener + } + val filesPath = BaresipService.filesPath + "/ca_certs.crt" + Utils.putFileContents(filesPath, content) + Config.removeVariable("sip_cafile") + Config.addLine("sip_cafile $filesPath") + caFile.isChecked = true + save = true + restart = true } - val filesPath = BaresipService.filesPath + "/ca_certs.crt" - Utils.putFileContents(filesPath, content) - Config.removeVariable("sip_cafile") - Config.addLine("sip_cafile $filesPath") - caFile.isChecked = true - save = true - restart = true - } else if (ActivityCompat.shouldShowRequestPermissionRationale( - this, - Manifest.permission.READ_EXTERNAL_STORAGE - ) - ) { - layout.showSnackBar( - binding.root, - getString(R.string.no_restore), - Snackbar.LENGTH_INDEFINITE, - getString(R.string.ok) - ) { + ActivityCompat.shouldShowRequestPermissionRationale( + this, + Manifest.permission.READ_EXTERNAL_STORAGE + ) -> { + layout.showSnackBar( + binding.root, + getString(R.string.no_restore), + Snackbar.LENGTH_INDEFINITE, + getString(R.string.ok) + ) { + requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE) + } + } + else -> { requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE) } - } else { - requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE) } } else { Utils.selectInputFile(certificatesRequest) diff --git a/app/src/main/kotlin/com/tutpro/baresip/Constants.kt b/app/src/main/kotlin/com/tutpro/baresip/Constants.kt index 679d12b5..c150a315 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/Constants.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/Constants.kt @@ -5,13 +5,8 @@ const val TAG = "Baresip" const val DEFAULT_CHANNEL_ID = "com.tutpro.baresip.default" const val HIGH_CHANNEL_ID = "com.tutpro.baresip.high" -const val BACKUP_PERMISSION_REQUEST_CODE = 1 -const val RESTORE_PERMISSION_REQUEST_CODE = 2 -const val CALL_PERMISSION_REQUEST_CODE = 3 -const val CONTACT_PERMISSION_REQUEST_CODE = 4 -const val READ_CERT_PERMISSION_CODE = 5 -const val READ_CA_PERMISSION_CODE = 6 -const val REQUEST_PERMISSIONS_CODE = 7 +const val CALL_PERMISSION_REQUEST_CODE = 1 +const val CONTACT_PERMISSION_REQUEST_CODE = 2 const val STATUS_NOTIFICATION_ID = 101 const val CALL_NOTIFICATION_ID = 102 diff --git a/app/src/main/kotlin/com/tutpro/baresip/ContactActivity.kt b/app/src/main/kotlin/com/tutpro/baresip/ContactActivity.kt index 05b8a711..ffb66fb3 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/ContactActivity.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/ContactActivity.kt @@ -207,39 +207,40 @@ class ContactActivity : AppCompatActivity() { override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grandResults: IntArray) { super.onRequestPermissionsResult(requestCode, permissions, grandResults) - var allowed = true when (requestCode) { - CONTACT_PERMISSION_REQUEST_CODE -> + CONTACT_PERMISSION_REQUEST_CODE -> { + var allowed = true for (res in grandResults) allowed = allowed && res == PackageManager.PERMISSION_GRANTED - } - if (!allowed) { - androidCheck.isChecked = oldAndroid - if (ActivityCompat.shouldShowRequestPermissionRationale( - this, - Manifest.permission.READ_CONTACTS - )) - { - layout.showSnackBar( - binding.root, - getString(R.string.no_android_contacts), - Snackbar.LENGTH_INDEFINITE, - getString(R.string.ok) - ) { - requestPermissionsLauncher.launch(permissions) - } - } else if (ActivityCompat.shouldShowRequestPermissionRationale( - this, - Manifest.permission.WRITE_CONTACTS - )) - { - layout.showSnackBar( - binding.root, - getString(R.string.no_android_contacts), - Snackbar.LENGTH_INDEFINITE, - getString(R.string.ok) - ) { - requestPermissionsLauncher.launch(permissions) + if (!allowed) { + androidCheck.isChecked = oldAndroid + when { + ActivityCompat.shouldShowRequestPermissionRationale(this, + Manifest.permission.READ_CONTACTS) -> { + layout.showSnackBar( + binding.root, + getString(R.string.no_android_contacts), + Snackbar.LENGTH_INDEFINITE, + getString(R.string.ok) + ) { + requestPermissionsLauncher.launch(permissions) + } + } + ActivityCompat.shouldShowRequestPermissionRationale(this, + Manifest.permission.WRITE_CONTACTS) -> { + layout.showSnackBar( + binding.root, + getString(R.string.no_android_contacts), + Snackbar.LENGTH_INDEFINITE, + getString(R.string.ok) + ) { + requestPermissionsLauncher.launch(permissions) + } + } + else -> { + requestPermissionsLauncher.launch(permissions) + } + } } } } diff --git a/app/src/main/kotlin/com/tutpro/baresip/MainActivity.kt b/app/src/main/kotlin/com/tutpro/baresip/MainActivity.kt index 2043909f..fd542efc 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/MainActivity.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/MainActivity.kt @@ -310,10 +310,12 @@ class MainActivity : AppCompatActivity() { callButton.setOnClickListener { if (aorSpinner.selectedItemPosition == -1) return@setOnClickListener - val permissions = arrayOf(Manifest.permission.RECORD_AUDIO, Manifest.permission.READ_PHONE_STATE) - if (Build.VERSION.SDK_INT >= 23) - if (!Utils.checkPermissions(this, permissions)) - requestPermissions(permissions, CALL_PERMISSION_REQUEST_CODE) + val permissions = arrayOf(Manifest.permission.RECORD_AUDIO) + if (Build.VERSION.SDK_INT < 23 || Utils.checkPermissions(this, permissions)) + makeCall() + else + ActivityCompat.requestPermissions(this, permissions, + CALL_PERMISSION_REQUEST_CODE) } hangupButton.setOnClickListener { @@ -722,89 +724,6 @@ class MainActivity : AppCompatActivity() { super.onDestroy() } - override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, - grandResults: IntArray) { - super.onRequestPermissionsResult(requestCode, permissions, grandResults) - var allowed = true - when (requestCode) { - CALL_PERMISSION_REQUEST_CODE -> { - for (res in grandResults) - allowed = allowed && res == PackageManager.PERMISSION_GRANTED - if (allowed) { - callUri.setAdapter(null) - val ua = UserAgent.uas()[aorSpinner.selectedItemPosition] - val aor = ua.account.aor - if (Call.calls().isEmpty()) { - val uriText = callUri.text.toString().trim() - if (uriText.isNotEmpty()) { - val uri = Utils.uriComplete( - ContactsActivity.findContactURI(uriText) - .filterNot { it.isWhitespace() }, - Utils.aorDomain(aor) - ) - if (!Utils.checkSipUri(uri)) { - Utils.alertView( - this, getString(R.string.notice), - String.format(getString(R.string.invalid_sip_uri), uri) - ) - } else { - callUri.isFocusable = false - if (!call(ua, uri)) { - callButton.visibility = View.VISIBLE - callButton.isEnabled = true - hangupButton.visibility = View.INVISIBLE - hangupButton.isEnabled = false - } else { - callButton.visibility = View.INVISIBLE - callButton.isEnabled = false - hangupButton.visibility = View.VISIBLE - hangupButton.isEnabled = true - } - } - } else { - val latest = CallHistory.aorLatestHistory(aor) - if (latest != null) - callUri.setText( - Utils.friendlyUri( - ContactsActivity.contactName(latest.peerUri), - Utils.aorDomain(ua.account.aor) - ) - ) - } - } - } else { - if (ActivityCompat.shouldShowRequestPermissionRationale( - this, - Manifest.permission.RECORD_AUDIO - ) - ) { - layout.showSnackBar( - binding.root, - getString(R.string.no_android_contacts), - Snackbar.LENGTH_INDEFINITE, - getString(R.string.ok) - ) { - requestPermissionsLauncher.launch(permissions) - } - } else if (ActivityCompat.shouldShowRequestPermissionRationale( - this, - Manifest.permission.READ_PHONE_STATE - ) - ) { - layout.showSnackBar( - binding.root, - getString(R.string.no_android_contacts), - Snackbar.LENGTH_INDEFINITE, - getString(R.string.ok) - ) { - requestPermissionsLauncher.launch(permissions) - } - } - } - } - } - } - override fun onNewIntent(intent: Intent) { // Called when MainActivity already exists at the top of current task super.onNewIntent(intent) @@ -1264,20 +1183,20 @@ class MainActivity : AppCompatActivity() { } R.id.backup -> { - if (Build.VERSION.SDK_INT >= 29) { - pickupFileFromDownloads("backup") - } else { - if (ContextCompat.checkSelfPermission( - this, - Manifest.permission.WRITE_EXTERNAL_STORAGE - ) == PackageManager.PERMISSION_GRANTED) { + when { + Build.VERSION.SDK_INT >= 29 -> pickupFileFromDownloads("backup") + ContextCompat.checkSelfPermission( + this, + Manifest.permission.WRITE_EXTERNAL_STORAGE + ) == PackageManager.PERMISSION_GRANTED -> { Log.d(TAG, "Write External Storage permission granted") val path = Utils.downloadsPath("baresip.bs") downloadsOutputStream = FileOutputStream(File(path)) askPassword(getString(R.string.encrypt_password)) - } else if (ActivityCompat.shouldShowRequestPermissionRationale( - this, - Manifest.permission.WRITE_EXTERNAL_STORAGE)) { + } + ActivityCompat.shouldShowRequestPermissionRationale( + this, + Manifest.permission.WRITE_EXTERNAL_STORAGE) -> { layout.showSnackBar( binding.root, getString(R.string.no_backup), @@ -1286,28 +1205,28 @@ class MainActivity : AppCompatActivity() { ) { requestPermissionLauncher.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE) } - } else { + } + else -> { requestPermissionLauncher.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE) } - } } R.id.restore -> { - if (Build.VERSION.SDK_INT >= 29) { - pickupFileFromDownloads("restore") - } else { - if (ContextCompat.checkSelfPermission( - this, - Manifest.permission.READ_EXTERNAL_STORAGE - ) == PackageManager.PERMISSION_GRANTED) { + when { + Build.VERSION.SDK_INT >= 29 -> pickupFileFromDownloads("restore") + ContextCompat.checkSelfPermission( + this, + Manifest.permission.READ_EXTERNAL_STORAGE + ) == PackageManager.PERMISSION_GRANTED -> { Log.d(TAG, "Read External Storage permission granted") val path = Utils.downloadsPath("baresip.bs") downloadsInputStream = FileInputStream(File(path)) askPassword(getString(R.string.decrypt_password)) - } else if (ActivityCompat.shouldShowRequestPermissionRationale( - this, - Manifest.permission.READ_EXTERNAL_STORAGE)) { + } + ActivityCompat.shouldShowRequestPermissionRationale( + this, + Manifest.permission.READ_EXTERNAL_STORAGE) -> { layout.showSnackBar( binding.root, getString(R.string.no_restore), @@ -1316,7 +1235,8 @@ class MainActivity : AppCompatActivity() { ) { requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE) } - } else { + } + else -> { requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE) } } @@ -1333,6 +1253,31 @@ class MainActivity : AppCompatActivity() { return true } + override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, + grantResults: IntArray) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + + when (requestCode) { + CALL_PERMISSION_REQUEST_CODE -> { + if ((grantResults.isNotEmpty()) && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) { + makeCall() + } else if (ActivityCompat.shouldShowRequestPermissionRationale(this, + Manifest.permission.RECORD_AUDIO)) { + layout.showSnackBar( + binding.root, + getString(R.string.no_calls), + Snackbar.LENGTH_INDEFINITE, + getString(R.string.ok) + ) { + requestPermissionLauncher.launch(Manifest.permission.RECORD_AUDIO) + } + } else { + requestPermissionLauncher.launch(Manifest.permission.RECORD_AUDIO) + } + } + } + } + @RequiresApi(29) private fun pickupFileFromDownloads(action: String) { when (action) { @@ -1666,6 +1611,50 @@ class MainActivity : AppCompatActivity() { } } + private fun makeCall() { + callUri.setAdapter(null) + val ua = UserAgent.uas()[aorSpinner.selectedItemPosition] + val aor = ua.account.aor + if (Call.calls().isEmpty()) { + val uriText = callUri.text.toString().trim() + if (uriText.isNotEmpty()) { + val uri = Utils.uriComplete( + ContactsActivity.findContactURI(uriText) + .filterNot { it.isWhitespace() }, + Utils.aorDomain(aor) + ) + if (!Utils.checkSipUri(uri)) { + Utils.alertView( + this, getString(R.string.notice), + String.format(getString(R.string.invalid_sip_uri), uri) + ) + } else { + callUri.isFocusable = false + if (!call(ua, uri)) { + callButton.visibility = View.VISIBLE + callButton.isEnabled = true + hangupButton.visibility = View.INVISIBLE + hangupButton.isEnabled = false + } else { + callButton.visibility = View.INVISIBLE + callButton.isEnabled = false + hangupButton.visibility = View.VISIBLE + hangupButton.isEnabled = true + } + } + } else { + val latest = CallHistory.aorLatestHistory(aor) + if (latest != null) + callUri.setText( + Utils.friendlyUri( + ContactsActivity.contactName(latest.peerUri), + Utils.aorDomain(ua.account.aor) + ) + ) + } + } + } + private fun showCall(ua: UserAgent) { if (Call.uaCalls(ua, "").size == 0) { swipeRefresh.isEnabled = true diff --git a/app/src/main/kotlin/com/tutpro/baresip/Utils.kt b/app/src/main/kotlin/com/tutpro/baresip/Utils.kt index bf03077e..8751231b 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/Utils.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/Utils.kt @@ -359,7 +359,7 @@ object Utils { fun checkPermissions(ctx: Context, permissions: Array) : Boolean { for (p in permissions) { if (ContextCompat.checkSelfPermission(ctx, p) != PackageManager.PERMISSION_GRANTED) { - Log.d(TAG, "Permission $p is not granted") + Log.d(TAG, "Permission $p is denied") return false } else { Log.d(TAG, "Permission $p is granted") diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 964e3143..879748ec 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -447,12 +447,12 @@ Failed to restore application data. Check that you gave correct password. In Android versions 9 and below, also check Apps → baresip → Permissions → Storage and that file \'%1$s\' exists in Download folder. - You are not able to make or answer calls without Microphone and - Telephone permissions. - You are not able create backup without Storage permission. + You are not able to make or answer calls without Microphone + permission. + You are not able create backup without \"Storage\" permission. You are not able add or remove Android contacts without - Contacts permission. - You are not able restore backup without Storage permission. + \"Contacts\" permission. + You are not able restore backup without \"Storage\" permission. Grant \"Camera\" permission to make or answer video calls. You don\'t have any supported video cameras. Show Password