diff --git a/CHANGES.md b/CHANGES.md index cdc9250841..37850e5bed 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -13,6 +13,7 @@ Other changes: Bugfix 🐛: - Fix issues with some member events rendering (#498) - Passphrase does not match (Export room keys) (#644) + - Ask for permission to write external storage when uri comes from the keyboard (#658) Translations 🗣: - 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 8f97ef0247..f8cdeb3de6 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 @@ -67,6 +67,7 @@ const val PERMISSION_REQUEST_CODE_EXPORT_KEYS = 573 const val PERMISSION_REQUEST_CODE_CHANGE_AVATAR = 574 const val PERMISSION_REQUEST_CODE_DOWNLOAD_FILE = 575 const val PERMISSION_REQUEST_CODE_PICK_ATTACHMENT = 576 +const val PERMISSION_REQUEST_CODE_INCOMING_URI = 577 /** * Log the used permissions statuses. diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt index 3c6625feeb..76d01228b8 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt @@ -81,8 +81,6 @@ import im.vector.riotx.core.platform.VectorBaseFragment import im.vector.riotx.core.ui.views.JumpToReadMarkerView import im.vector.riotx.core.ui.views.NotificationAreaView import im.vector.riotx.core.utils.* -import im.vector.riotx.core.utils.Debouncer -import im.vector.riotx.core.utils.createUIHandler import im.vector.riotx.features.attachments.AttachmentTypeSelectorView import im.vector.riotx.features.attachments.AttachmentsHelper import im.vector.riotx.features.attachments.ContactAttachment @@ -619,19 +617,27 @@ class RoomDetailFragment : } composerLayout.callback = object : TextComposerView.Callback { override fun onRichContentSelected(contentUri: Uri): Boolean { - val shareIntent = Intent().apply { - action = Intent.ACTION_SEND - data = contentUri + // We need WRITE_EXTERNAL permission + return if (checkPermissions(PERMISSIONS_FOR_WRITING_FILES, this@RoomDetailFragment, PERMISSION_REQUEST_CODE_INCOMING_URI)) { + sendUri(contentUri) + } else { + roomDetailViewModel.pendingUri = contentUri + // Always intercept when we request some permission + true } - val isHandled = attachmentsHelper.handleShareIntent(shareIntent) - if (!isHandled) { - Toast.makeText(requireContext(), R.string.error_handling_incoming_share, Toast.LENGTH_SHORT).show() - } - return isHandled } } } + private fun sendUri(uri: Uri): Boolean { + val shareIntent = Intent(Intent.ACTION_SEND, uri) + val isHandled = attachmentsHelper.handleShareIntent(shareIntent) + if (!isHandled) { + Toast.makeText(requireContext(), R.string.error_handling_incoming_share, Toast.LENGTH_SHORT).show() + } + return isHandled + } + private fun setupAttachmentButton() { composerLayout.attachmentButton.setOnClickListener { if (!::attachmentTypeSelector.isInitialized) { @@ -906,19 +912,34 @@ class RoomDetailFragment : override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { if (allGranted(grantResults)) { - if (requestCode == PERMISSION_REQUEST_CODE_DOWNLOAD_FILE) { - val action = roomDetailViewModel.pendingAction - if (action != null) { - roomDetailViewModel.pendingAction = null - roomDetailViewModel.process(action) + when (requestCode) { + PERMISSION_REQUEST_CODE_DOWNLOAD_FILE -> { + val action = roomDetailViewModel.pendingAction + if (action != null) { + roomDetailViewModel.pendingAction = null + roomDetailViewModel.process(action) + } } - } else if (requestCode == PERMISSION_REQUEST_CODE_PICK_ATTACHMENT) { - val pendingType = attachmentsHelper.pendingType - if (pendingType != null) { - attachmentsHelper.pendingType = null - launchAttachmentProcess(pendingType) + PERMISSION_REQUEST_CODE_INCOMING_URI -> { + val pendingUri = roomDetailViewModel.pendingUri + if (pendingUri != null) { + roomDetailViewModel.pendingUri = null + sendUri(pendingUri) + } + } + PERMISSION_REQUEST_CODE_PICK_ATTACHMENT -> { + val pendingType = attachmentsHelper.pendingType + if (pendingType != null) { + attachmentsHelper.pendingType = null + launchAttachmentProcess(pendingType) + } } } + } else { + // Reset all pending data + roomDetailViewModel.pendingAction = null + roomDetailViewModel.pendingUri = null + attachmentsHelper.pendingType = null } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt index f3934f618c..b1c6aa02fb 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt @@ -16,6 +16,7 @@ package im.vector.riotx.features.home.room.detail +import android.net.Uri import androidx.annotation.IdRes import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData @@ -95,6 +96,8 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro // Slot to keep a pending action during permission request var pendingAction: RoomDetailActions? = null + // Slot to keep a pending uri during permission request + var pendingUri: Uri? = null @AssistedInject.Factory interface Factory {