From 7388a408b842cdf5283db5c24096e1398e3bfb09 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 22 Oct 2019 17:13:38 +0200 Subject: [PATCH] Permissions: allow to provide the rationale message as it requires "context" and cannot be generic --- .../riotx/core/utils/PermissionsTools.kt | 68 ++++--------------- .../setup/KeysBackupSetupActivity.kt | 2 +- .../setup/KeysBackupSetupStep3Fragment.kt | 8 ++- .../room/detail/composer/ComposerEditText.kt | 1 - .../VectorSettingsSecurityPrivacyFragment.kt | 2 +- vector/src/main/res/values/strings.xml | 3 + 6 files changed, 24 insertions(+), 60 deletions(-) diff --git a/vector/src/main/java/im/vector/riotx/core/utils/PermissionsTools.kt b/vector/src/main/java/im/vector/riotx/core/utils/PermissionsTools.kt index a7aab97f36..2c03bcb943 100644 --- a/vector/src/main/java/im/vector/riotx/core/utils/PermissionsTools.kt +++ b/vector/src/main/java/im/vector/riotx/core/utils/PermissionsTools.kt @@ -21,8 +21,8 @@ import android.app.Activity import android.content.Context import android.content.pm.PackageManager import android.os.Build -import android.text.TextUtils import android.widget.Toast +import androidx.annotation.StringRes import androidx.appcompat.app.AlertDialog import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat @@ -102,8 +102,9 @@ fun logPermissionStatuses(context: Context) { */ fun checkPermissions(permissionsToBeGrantedBitMap: Int, activity: Activity, - requestCode: Int = PERMISSION_REQUEST_CODE): Boolean { - return checkPermissions(permissionsToBeGrantedBitMap, activity, null, requestCode) + requestCode: Int, + @StringRes rationaleMessage: Int = 0): Boolean { + return checkPermissions(permissionsToBeGrantedBitMap, activity, null, requestCode, rationaleMessage) } /** @@ -115,8 +116,9 @@ fun checkPermissions(permissionsToBeGrantedBitMap: Int, */ fun checkPermissions(permissionsToBeGrantedBitMap: Int, fragment: Fragment, - requestCode: Int = PERMISSION_REQUEST_CODE): Boolean { - return checkPermissions(permissionsToBeGrantedBitMap, fragment.activity, fragment, requestCode) + requestCode: Int, + @StringRes rationaleMessage: Int = 0): Boolean { + return checkPermissions(permissionsToBeGrantedBitMap, fragment.activity, fragment, requestCode, rationaleMessage) } /** @@ -140,7 +142,9 @@ fun checkPermissions(permissionsToBeGrantedBitMap: Int, private fun checkPermissions(permissionsToBeGrantedBitMap: Int, activity: Activity?, fragment: Fragment?, - requestCode: Int): Boolean { + requestCode: Int, + @StringRes rationaleMessage: Int + ): Boolean { var isPermissionGranted = false // sanity check @@ -163,7 +167,6 @@ private fun checkPermissions(permissionsToBeGrantedBitMap: Int, val permissionListAlreadyDenied = ArrayList() val permissionsListToBeGranted = ArrayList() var isRequestPermissionRequired = false - var explanationMessage = "" // retrieve the permissions to be granted according to the request code bit map if (PERMISSION_CAMERA == permissionsToBeGrantedBitMap and PERMISSION_CAMERA) { @@ -203,58 +206,11 @@ private fun checkPermissions(permissionsToBeGrantedBitMap: Int, } // if some permissions were already denied: display a dialog to the user before asking again. - if (!permissionListAlreadyDenied.isEmpty()) { - if (permissionsToBeGrantedBitMap == PERMISSIONS_FOR_VIDEO_IP_CALL || permissionsToBeGrantedBitMap == PERMISSIONS_FOR_AUDIO_IP_CALL) { - // Permission request for VOIP call - if (permissionListAlreadyDenied.contains(Manifest.permission.CAMERA) - && permissionListAlreadyDenied.contains(Manifest.permission.RECORD_AUDIO)) { - // Both missing - explanationMessage += activity.getString(R.string.permissions_rationale_msg_camera_and_audio) - } else if (permissionListAlreadyDenied.contains(Manifest.permission.RECORD_AUDIO)) { - // Audio missing - explanationMessage += activity.getString(R.string.permissions_rationale_msg_record_audio) - explanationMessage += activity.getString(R.string.permissions_rationale_msg_record_audio_explanation) - } else if (permissionListAlreadyDenied.contains(Manifest.permission.CAMERA)) { - // Camera missing - explanationMessage += activity.getString(R.string.permissions_rationale_msg_camera) - explanationMessage += activity.getString(R.string.permissions_rationale_msg_camera_explanation) - } - } else { - permissionListAlreadyDenied.forEach { - when (it) { - Manifest.permission.CAMERA -> { - if (!TextUtils.isEmpty(explanationMessage)) { - explanationMessage += "\n\n" - } - explanationMessage += activity.getString(R.string.permissions_rationale_msg_camera) - } - Manifest.permission.RECORD_AUDIO -> { - if (!TextUtils.isEmpty(explanationMessage)) { - explanationMessage += "\n\n" - } - explanationMessage += activity.getString(R.string.permissions_rationale_msg_record_audio) - } - Manifest.permission.WRITE_EXTERNAL_STORAGE -> { - if (!TextUtils.isEmpty(explanationMessage)) { - explanationMessage += "\n\n" - } - explanationMessage += activity.getString(R.string.permissions_rationale_msg_storage) - } - Manifest.permission.READ_CONTACTS -> { - if (!TextUtils.isEmpty(explanationMessage)) { - explanationMessage += "\n\n" - } - explanationMessage += activity.getString(R.string.permissions_rationale_msg_contacts) - } - else -> Timber.v("## checkPermissions(): already denied permission not supported") - } - } - } - + if (permissionListAlreadyDenied.isNotEmpty() && rationaleMessage != 0) { // display the dialog with the info text AlertDialog.Builder(activity) .setTitle(R.string.permissions_rationale_popup_title) - .setMessage(explanationMessage) + .setMessage(rationaleMessage) .setOnCancelListener { Toast.makeText(activity, R.string.missing_permissions_warning, Toast.LENGTH_SHORT).show() } .setPositiveButton(R.string.ok) { _, _ -> if (!permissionsListToBeGranted.isEmpty()) { diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupActivity.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupActivity.kt index 291da66362..6868fb84bb 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupActivity.kt @@ -130,7 +130,7 @@ class KeysBackupSetupActivity : SimpleFragmentActivity() { } private fun exportKeysManually() { - if (checkPermissions(PERMISSIONS_FOR_WRITING_FILES, this, PERMISSION_REQUEST_CODE_EXPORT_KEYS)) { + if (checkPermissions(PERMISSIONS_FOR_WRITING_FILES, this, PERMISSION_REQUEST_CODE_EXPORT_KEYS, R.string.permissions_rationale_msg_keys_backup_export)) { ExportKeysDialog().show(this, object : ExportKeysDialog.ExportKeyDialogListener { override fun onPassphrase(passphrase: String) { showWaitingView() diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep3Fragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep3Fragment.kt index 4a7514416d..7b61ca2c0f 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep3Fragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep3Fragment.kt @@ -135,7 +135,13 @@ class KeysBackupSetupStep3Fragment : VectorBaseFragment() { } dialog.findViewById(R.id.keys_backup_setup_save)?.setOnClickListener { - if (checkPermissions(PERMISSIONS_FOR_WRITING_FILES, this, PERMISSION_REQUEST_CODE_EXPORT_KEYS)) { + val permissionsChecked = checkPermissions( + PERMISSIONS_FOR_WRITING_FILES, + this, + PERMISSION_REQUEST_CODE_EXPORT_KEYS, + R.string.permissions_rationale_msg_keys_backup_export + ) + if (permissionsChecked) { exportRecoveryKeyToFile(recoveryKey) } dialog.dismiss() diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/ComposerEditText.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/ComposerEditText.kt index 3b1165b016..9c894df880 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/ComposerEditText.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/ComposerEditText.kt @@ -52,7 +52,6 @@ class ComposerEditText @JvmOverloads constructor(context: Context, attrs: Attrib } } callback?.onRichContentSelected(inputContentInfo.contentUri) ?: false - } return InputConnectionCompat.createWrapper(ic, editorInfo, callback) } diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsSecurityPrivacyFragment.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsSecurityPrivacyFragment.kt index dfc7004554..55805434fa 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsSecurityPrivacyFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsSecurityPrivacyFragment.kt @@ -212,7 +212,7 @@ class VectorSettingsSecurityPrivacyFragment : VectorSettingsBaseFragment() { */ private fun exportKeys() { // We need WRITE_EXTERNAL permission - if (checkPermissions(PERMISSIONS_FOR_WRITING_FILES, this, PERMISSION_REQUEST_CODE_EXPORT_KEYS)) { + if (checkPermissions(PERMISSIONS_FOR_WRITING_FILES, this, PERMISSION_REQUEST_CODE_EXPORT_KEYS, R.string.permissions_rationale_msg_keys_backup_export)) { activity?.let { activity -> ExportKeysDialog().show(activity, object : ExportKeysDialog.ExportKeyDialogListener { override fun onPassphrase(passphrase: String) { diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 8b83175784..ca5a37ee84 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -368,6 +368,9 @@ Riot needs permission to access your camera and your microphone to perform video calls.\n\nPlease allow access on the next pop-ups to be able to make the call. Riot can check your address book to find other Matrix users based on their email and phone numbers. If you agree to share your address book for this purpose, please allow access on the next pop-up. Riot can check your address book to find other Matrix users based on their email and phone numbers.\n\nDo you agree to share your address book for this purpose? + Riot needs permission to save your E2E keys on disk.\n\nPlease allow access on the next pop-up to be able to export your keys manually. + + Sorry. Action not performed, due to missing permissions