mirror of
https://github.com/element-hq/element-android
synced 2024-11-28 13:38:49 +03:00
Permissions: allow to provide the rationale message as it requires "context" and cannot be generic
This commit is contained in:
parent
c7a4d34192
commit
7388a408b8
6 changed files with 24 additions and 60 deletions
|
@ -21,8 +21,8 @@ import android.app.Activity
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.text.TextUtils
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
import androidx.annotation.StringRes
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
|
@ -102,8 +102,9 @@ fun logPermissionStatuses(context: Context) {
|
||||||
*/
|
*/
|
||||||
fun checkPermissions(permissionsToBeGrantedBitMap: Int,
|
fun checkPermissions(permissionsToBeGrantedBitMap: Int,
|
||||||
activity: Activity,
|
activity: Activity,
|
||||||
requestCode: Int = PERMISSION_REQUEST_CODE): Boolean {
|
requestCode: Int,
|
||||||
return checkPermissions(permissionsToBeGrantedBitMap, activity, null, requestCode)
|
@StringRes rationaleMessage: Int = 0): Boolean {
|
||||||
|
return checkPermissions(permissionsToBeGrantedBitMap, activity, null, requestCode, rationaleMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -115,8 +116,9 @@ fun checkPermissions(permissionsToBeGrantedBitMap: Int,
|
||||||
*/
|
*/
|
||||||
fun checkPermissions(permissionsToBeGrantedBitMap: Int,
|
fun checkPermissions(permissionsToBeGrantedBitMap: Int,
|
||||||
fragment: Fragment,
|
fragment: Fragment,
|
||||||
requestCode: Int = PERMISSION_REQUEST_CODE): Boolean {
|
requestCode: Int,
|
||||||
return checkPermissions(permissionsToBeGrantedBitMap, fragment.activity, fragment, requestCode)
|
@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,
|
private fun checkPermissions(permissionsToBeGrantedBitMap: Int,
|
||||||
activity: Activity?,
|
activity: Activity?,
|
||||||
fragment: Fragment?,
|
fragment: Fragment?,
|
||||||
requestCode: Int): Boolean {
|
requestCode: Int,
|
||||||
|
@StringRes rationaleMessage: Int
|
||||||
|
): Boolean {
|
||||||
var isPermissionGranted = false
|
var isPermissionGranted = false
|
||||||
|
|
||||||
// sanity check
|
// sanity check
|
||||||
|
@ -163,7 +167,6 @@ private fun checkPermissions(permissionsToBeGrantedBitMap: Int,
|
||||||
val permissionListAlreadyDenied = ArrayList<String>()
|
val permissionListAlreadyDenied = ArrayList<String>()
|
||||||
val permissionsListToBeGranted = ArrayList<String>()
|
val permissionsListToBeGranted = ArrayList<String>()
|
||||||
var isRequestPermissionRequired = false
|
var isRequestPermissionRequired = false
|
||||||
var explanationMessage = ""
|
|
||||||
|
|
||||||
// retrieve the permissions to be granted according to the request code bit map
|
// retrieve the permissions to be granted according to the request code bit map
|
||||||
if (PERMISSION_CAMERA == permissionsToBeGrantedBitMap and PERMISSION_CAMERA) {
|
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 some permissions were already denied: display a dialog to the user before asking again.
|
||||||
if (!permissionListAlreadyDenied.isEmpty()) {
|
if (permissionListAlreadyDenied.isNotEmpty() && rationaleMessage != 0) {
|
||||||
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")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// display the dialog with the info text
|
// display the dialog with the info text
|
||||||
AlertDialog.Builder(activity)
|
AlertDialog.Builder(activity)
|
||||||
.setTitle(R.string.permissions_rationale_popup_title)
|
.setTitle(R.string.permissions_rationale_popup_title)
|
||||||
.setMessage(explanationMessage)
|
.setMessage(rationaleMessage)
|
||||||
.setOnCancelListener { Toast.makeText(activity, R.string.missing_permissions_warning, Toast.LENGTH_SHORT).show() }
|
.setOnCancelListener { Toast.makeText(activity, R.string.missing_permissions_warning, Toast.LENGTH_SHORT).show() }
|
||||||
.setPositiveButton(R.string.ok) { _, _ ->
|
.setPositiveButton(R.string.ok) { _, _ ->
|
||||||
if (!permissionsListToBeGranted.isEmpty()) {
|
if (!permissionsListToBeGranted.isEmpty()) {
|
||||||
|
|
|
@ -130,7 +130,7 @@ class KeysBackupSetupActivity : SimpleFragmentActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun exportKeysManually() {
|
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 {
|
ExportKeysDialog().show(this, object : ExportKeysDialog.ExportKeyDialogListener {
|
||||||
override fun onPassphrase(passphrase: String) {
|
override fun onPassphrase(passphrase: String) {
|
||||||
showWaitingView()
|
showWaitingView()
|
||||||
|
|
|
@ -135,7 +135,13 @@ class KeysBackupSetupStep3Fragment : VectorBaseFragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
dialog.findViewById<View>(R.id.keys_backup_setup_save)?.setOnClickListener {
|
dialog.findViewById<View>(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)
|
exportRecoveryKeyToFile(recoveryKey)
|
||||||
}
|
}
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
|
|
|
@ -52,7 +52,6 @@ class ComposerEditText @JvmOverloads constructor(context: Context, attrs: Attrib
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
callback?.onRichContentSelected(inputContentInfo.contentUri) ?: false
|
callback?.onRichContentSelected(inputContentInfo.contentUri) ?: false
|
||||||
|
|
||||||
}
|
}
|
||||||
return InputConnectionCompat.createWrapper(ic, editorInfo, callback)
|
return InputConnectionCompat.createWrapper(ic, editorInfo, callback)
|
||||||
}
|
}
|
||||||
|
|
|
@ -212,7 +212,7 @@ class VectorSettingsSecurityPrivacyFragment : VectorSettingsBaseFragment() {
|
||||||
*/
|
*/
|
||||||
private fun exportKeys() {
|
private fun exportKeys() {
|
||||||
// We need WRITE_EXTERNAL permission
|
// 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 ->
|
activity?.let { activity ->
|
||||||
ExportKeysDialog().show(activity, object : ExportKeysDialog.ExportKeyDialogListener {
|
ExportKeysDialog().show(activity, object : ExportKeysDialog.ExportKeyDialogListener {
|
||||||
override fun onPassphrase(passphrase: String) {
|
override fun onPassphrase(passphrase: String) {
|
||||||
|
|
|
@ -368,6 +368,9 @@
|
||||||
<string name="permissions_rationale_msg_camera_and_audio">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.</string>
|
<string name="permissions_rationale_msg_camera_and_audio">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.</string>
|
||||||
<string name="permissions_rationale_msg_contacts">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.</string>
|
<string name="permissions_rationale_msg_contacts">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.</string>
|
||||||
<string name="permissions_msg_contacts_warning_other_androids">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?</string>
|
<string name="permissions_msg_contacts_warning_other_androids">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?</string>
|
||||||
|
<string name="permissions_rationale_msg_keys_backup_export">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.</string>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<string name="permissions_action_not_performed_missing_permissions">Sorry. Action not performed, due to missing permissions</string>
|
<string name="permissions_action_not_performed_missing_permissions">Sorry. Action not performed, due to missing permissions</string>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue