From ad76cbbc405a6c611f5e3e1486c64f9dfd9475a6 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 5 Jul 2022 13:22:52 +0100 Subject: [PATCH 1/4] adding tests around share intent handling --- .../attachments/MultiPickerIncomingFiles.kt | 37 ++++ .../attachments/ShareIntentHandler.kt | 40 +---- .../attachments/ShareIntentHandlerTest.kt | 166 ++++++++++++++++++ .../im/vector/app/test/fakes/FakeFunction1.kt | 36 ++++ .../im/vector/app/test/fakes/FakeIntent.kt | 35 ++++ .../fakes/FakeMultiPickerIncomingFiles.kt | 44 +++++ .../fixtures/ContentAttachmentDataFixture.kt | 29 +++ 7 files changed, 354 insertions(+), 33 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/attachments/MultiPickerIncomingFiles.kt create mode 100644 vector/src/test/java/im/vector/app/features/attachments/ShareIntentHandlerTest.kt create mode 100644 vector/src/test/java/im/vector/app/test/fakes/FakeFunction1.kt create mode 100644 vector/src/test/java/im/vector/app/test/fakes/FakeIntent.kt create mode 100644 vector/src/test/java/im/vector/app/test/fakes/FakeMultiPickerIncomingFiles.kt create mode 100644 vector/src/test/java/im/vector/app/test/fixtures/ContentAttachmentDataFixture.kt diff --git a/vector/src/main/java/im/vector/app/features/attachments/MultiPickerIncomingFiles.kt b/vector/src/main/java/im/vector/app/features/attachments/MultiPickerIncomingFiles.kt new file mode 100644 index 0000000000..82da3a795f --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/attachments/MultiPickerIncomingFiles.kt @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.attachments + +import android.content.Context +import android.content.Intent +import im.vector.lib.multipicker.MultiPicker +import javax.inject.Inject + +class MultiPickerIncomingFiles @Inject constructor( + private val context: Context, +) { + + fun image(intent: Intent) = MultiPicker.get(MultiPicker.IMAGE).getIncomingFiles(context, intent).map { it.toContentAttachmentData() } + + fun video(intent: Intent) = MultiPicker.get(MultiPicker.VIDEO).getIncomingFiles(context, intent).map { it.toContentAttachmentData() } + + fun media(intent: Intent) = MultiPicker.get(MultiPicker.MEDIA).getIncomingFiles(context, intent).map { it.toContentAttachmentData() } + + fun file(intent: Intent) = MultiPicker.get(MultiPicker.FILE).getIncomingFiles(context, intent).map { it.toContentAttachmentData() } + + fun audio(intent: Intent) = MultiPicker.get(MultiPicker.AUDIO).getIncomingFiles(context, intent).map { it.toContentAttachmentData() } +} diff --git a/vector/src/main/java/im/vector/app/features/attachments/ShareIntentHandler.kt b/vector/src/main/java/im/vector/app/features/attachments/ShareIntentHandler.kt index 06ca949025..8cd20d36c1 100644 --- a/vector/src/main/java/im/vector/app/features/attachments/ShareIntentHandler.kt +++ b/vector/src/main/java/im/vector/app/features/attachments/ShareIntentHandler.kt @@ -18,11 +18,12 @@ package im.vector.app.features.attachments import android.content.Context import android.content.Intent -import im.vector.lib.multipicker.MultiPicker import org.matrix.android.sdk.api.session.content.ContentAttachmentData import javax.inject.Inject -class ShareIntentHandler @Inject constructor() { +class ShareIntentHandler @Inject constructor( + private val multiPickerIncomingFiles: MultiPickerIncomingFiles, +) { /** * This methods aims to handle incoming share intents. @@ -33,38 +34,11 @@ class ShareIntentHandler @Inject constructor() { val type = intent.resolveType(context) ?: return false return when { type == "text/plain" -> handlePlainText(intent, onPlainText) - type.startsWith("image") -> { - onFile( - MultiPicker.get(MultiPicker.IMAGE).getIncomingFiles(context, intent).map { - it.toContentAttachmentData() - } - ) - true - } - type.startsWith("video") -> { - onFile( - MultiPicker.get(MultiPicker.VIDEO).getIncomingFiles(context, intent).map { - it.toContentAttachmentData() - } - ) - true - } - type.startsWith("audio") -> { - onFile( - MultiPicker.get(MultiPicker.AUDIO).getIncomingFiles(context, intent).map { - it.toContentAttachmentData() - } - ) - true - } - + type.startsWith("image") -> onFile(multiPickerIncomingFiles.image(intent)).let { true } + type.startsWith("video") -> onFile(multiPickerIncomingFiles.video(intent)).let { true } + type.startsWith("audio") -> onFile(multiPickerIncomingFiles.audio(intent)).let { true } type.startsWith("application") || type.startsWith("file") || type.startsWith("text") || type.startsWith("*") -> { - onFile( - MultiPicker.get(MultiPicker.FILE).getIncomingFiles(context, intent).map { - it.toContentAttachmentData() - } - ) - true + onFile(multiPickerIncomingFiles.file(intent)).let { true } } else -> false } diff --git a/vector/src/test/java/im/vector/app/features/attachments/ShareIntentHandlerTest.kt b/vector/src/test/java/im/vector/app/features/attachments/ShareIntentHandlerTest.kt new file mode 100644 index 0000000000..bb3aabf67f --- /dev/null +++ b/vector/src/test/java/im/vector/app/features/attachments/ShareIntentHandlerTest.kt @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.attachments + +import android.content.Intent +import im.vector.app.test.fakes.FakeContext +import im.vector.app.test.fakes.FakeFunction1 +import im.vector.app.test.fakes.FakeIntent +import im.vector.app.test.fakes.FakeMultiPickerIncomingFiles +import im.vector.app.test.fixtures.ContentAttachmentDataFixture.aContentAttachmentData +import org.amshove.kluent.shouldBeEqualTo +import org.junit.Test +import org.matrix.android.sdk.api.session.content.ContentAttachmentData + +private val A_CONTEXT = FakeContext().instance +private const val A_PLAIN_TEXT_EXTRA = "plain text for sharing" +private val A_CONTENT_ATTACHMENT_LIST = listOf(aContentAttachmentData()) + +class ShareIntentHandlerTest { + + private val fakeMultiPickerIncomingFiles = FakeMultiPickerIncomingFiles() + private val onFile = FakeFunction1>() + private val onPlainText = FakeFunction1() + + private val shareIntentHandler = ShareIntentHandler(fakeMultiPickerIncomingFiles.instance) + + @Test + fun `given an unhandled sharing intent type, when handling intent, then is not handled`() { + val unknownShareIntent = FakeIntent().also { it.givenResolvesType(A_CONTEXT, "unknown/type") } + + val handled = handleIncomingShareIntent(unknownShareIntent) + + onFile.verifyNoInteractions() + onPlainText.verifyNoInteractions() + handled shouldBeEqualTo false + } + + @Test + fun `given a plain text sharing intent, when handling intent, then is handled and parses plain text content`() { + val plainTextShareIntent = FakeIntent().also { + it.givenResolvesType(A_CONTEXT, "text/plain") + it.givenCharSequenceExtra(key = Intent.EXTRA_TEXT, value = A_PLAIN_TEXT_EXTRA) + } + + val handled = handleIncomingShareIntent(plainTextShareIntent) + + onFile.verifyNoInteractions() + onPlainText.assertValue(A_PLAIN_TEXT_EXTRA) + handled shouldBeEqualTo true + } + + @Test + fun `given an empty plain text sharing intent, when handling intent, then is not handled`() { + val plainTextShareIntent = FakeIntent().also { + it.givenResolvesType(A_CONTEXT, "text/plain") + it.givenCharSequenceExtra(key = Intent.EXTRA_TEXT, value = "") + } + + val handled = handleIncomingShareIntent(plainTextShareIntent) + + onFile.verifyNoInteractions() + onPlainText.verifyNoInteractions() + handled shouldBeEqualTo false + } + + @Test + fun `given an image sharing intent, when handling intent, then is handled and parses image files`() { + val imageShareIntent = FakeIntent().also { it.givenResolvesType(A_CONTEXT, "image/png") } + fakeMultiPickerIncomingFiles.givenImageReturns(imageShareIntent.instance, A_CONTENT_ATTACHMENT_LIST) + + val handled = handleIncomingShareIntent(imageShareIntent) + + onFile.assertValue(A_CONTENT_ATTACHMENT_LIST) + onPlainText.verifyNoInteractions() + handled shouldBeEqualTo true + } + + @Test + fun `given an audio sharing intent, when handling intent, then is handled and parses audio files`() { + val audioShareIntent = FakeIntent().also { it.givenResolvesType(A_CONTEXT, "audio/mp3") } + fakeMultiPickerIncomingFiles.givenAudioReturns(audioShareIntent.instance, A_CONTENT_ATTACHMENT_LIST) + + val handled = handleIncomingShareIntent(audioShareIntent) + + onFile.assertValue(A_CONTENT_ATTACHMENT_LIST) + onPlainText.verifyNoInteractions() + handled shouldBeEqualTo true + } + + @Test + fun `given an video sharing intent, when handling intent, then is handled and parses video files`() { + val videoShareIntent = FakeIntent().also { it.givenResolvesType(A_CONTEXT, "video/mp4") } + fakeMultiPickerIncomingFiles.givenVideoReturns(videoShareIntent.instance, A_CONTENT_ATTACHMENT_LIST) + + val handled = handleIncomingShareIntent(videoShareIntent) + + onFile.assertValue(A_CONTENT_ATTACHMENT_LIST) + onPlainText.verifyNoInteractions() + handled shouldBeEqualTo true + } + + @Test + fun `given a file sharing intent, when handling intent, then is handled and parses files`() { + val fileShareIntent = FakeIntent().also { it.givenResolvesType(A_CONTEXT, "file/*") } + fakeMultiPickerIncomingFiles.givenFileReturns(fileShareIntent.instance, A_CONTENT_ATTACHMENT_LIST) + + val handled = handleIncomingShareIntent(fileShareIntent) + + onFile.assertValue(A_CONTENT_ATTACHMENT_LIST) + onPlainText.verifyNoInteractions() + handled shouldBeEqualTo true + } + + @Test + fun `given a application sharing intent, when handling intent, then is handled and parses files`() { + val fileShareIntent = FakeIntent().also { it.givenResolvesType(A_CONTEXT, "application/apk") } + fakeMultiPickerIncomingFiles.givenFileReturns(fileShareIntent.instance, A_CONTENT_ATTACHMENT_LIST) + + handleIncomingShareIntent(fileShareIntent) + + onFile.assertValue(A_CONTENT_ATTACHMENT_LIST) + onPlainText.verifyNoInteractions() + } + + @Test + fun `given a text sharing intent, when handling intent, then is handled and parses text files`() { + val fileShareIntent = FakeIntent().also { it.givenResolvesType(A_CONTEXT, "text/ics") } + fakeMultiPickerIncomingFiles.givenFileReturns(fileShareIntent.instance, A_CONTENT_ATTACHMENT_LIST) + + val handled = handleIncomingShareIntent(fileShareIntent) + + onFile.assertValue(A_CONTENT_ATTACHMENT_LIST) + onPlainText.verifyNoInteractions() + handled shouldBeEqualTo true + } + + @Test + fun `given a wildcard sharing intent, when handling intent, then is handled and parses files`() { + val fileShareIntent = FakeIntent().also { it.givenResolvesType(A_CONTEXT, "*/*") } + fakeMultiPickerIncomingFiles.givenFileReturns(fileShareIntent.instance, A_CONTENT_ATTACHMENT_LIST) + + val handled = handleIncomingShareIntent(fileShareIntent) + + onFile.assertValue(A_CONTENT_ATTACHMENT_LIST) + onPlainText.verifyNoInteractions() + handled shouldBeEqualTo true + } + + private fun handleIncomingShareIntent(intent: FakeIntent): Boolean { + return shareIntentHandler.handleIncomingShareIntent(A_CONTEXT, intent.instance, onFile.capture, onPlainText.capture) + } +} diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeFunction1.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeFunction1.kt new file mode 100644 index 0000000000..434a661e5f --- /dev/null +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeFunction1.kt @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.test.fakes + +import org.amshove.kluent.shouldBeEqualTo + +class FakeFunction1 { + + private lateinit var capturedValue: T + + val capture: (T) -> Unit = { + capturedValue = it + } + + fun verifyNoInteractions() { + this::capturedValue.isInitialized shouldBeEqualTo false + } + + fun assertValue(value: T) { + capturedValue shouldBeEqualTo value + } +} diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeIntent.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeIntent.kt new file mode 100644 index 0000000000..1b3ce3538e --- /dev/null +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeIntent.kt @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.test.fakes + +import android.content.Context +import android.content.Intent +import io.mockk.every +import io.mockk.mockk + +class FakeIntent { + + val instance = mockk() + + fun givenResolvesType(context: Context, type: String?) { + every { instance.resolveType(context) } returns type + } + + fun givenCharSequenceExtra(key: String, value: CharSequence) { + every { instance.getCharSequenceExtra(key) } returns value + } +} diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeMultiPickerIncomingFiles.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeMultiPickerIncomingFiles.kt new file mode 100644 index 0000000000..00adc83e5c --- /dev/null +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeMultiPickerIncomingFiles.kt @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.test.fakes + +import android.content.Intent +import im.vector.app.features.attachments.MultiPickerIncomingFiles +import io.mockk.every +import io.mockk.mockk +import org.matrix.android.sdk.api.session.content.ContentAttachmentData + +class FakeMultiPickerIncomingFiles { + + val instance = mockk() + + fun givenFileReturns(intent: Intent, result: List) { + every { instance.file(intent) } returns result + } + + fun givenAudioReturns(intent: Intent, result: List) { + every { instance.audio(intent) } returns result + } + + fun givenVideoReturns(intent: Intent, result: List) { + every { instance.video(intent) } returns result + } + + fun givenImageReturns(intent: Intent, result: List) { + every { instance.image(intent) } returns result + } +} diff --git a/vector/src/test/java/im/vector/app/test/fixtures/ContentAttachmentDataFixture.kt b/vector/src/test/java/im/vector/app/test/fixtures/ContentAttachmentDataFixture.kt new file mode 100644 index 0000000000..731d6b32d0 --- /dev/null +++ b/vector/src/test/java/im/vector/app/test/fixtures/ContentAttachmentDataFixture.kt @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.test.fixtures + +import im.vector.app.test.fakes.FakeUri +import org.matrix.android.sdk.api.session.content.ContentAttachmentData + +object ContentAttachmentDataFixture { + + fun aContentAttachmentData() = ContentAttachmentData( + type = ContentAttachmentData.Type.AUDIO, + queryUri = FakeUri().instance, + mimeType = null, + ) +} From d19346b9c65ac45a0e5fd4cc728b576374f1a031 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 5 Jul 2022 13:46:24 +0100 Subject: [PATCH 2/4] fixing formatting --- .../vector/app/features/attachments/MultiPickerIncomingFiles.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/attachments/MultiPickerIncomingFiles.kt b/vector/src/main/java/im/vector/app/features/attachments/MultiPickerIncomingFiles.kt index 82da3a795f..0f2dad541c 100644 --- a/vector/src/main/java/im/vector/app/features/attachments/MultiPickerIncomingFiles.kt +++ b/vector/src/main/java/im/vector/app/features/attachments/MultiPickerIncomingFiles.kt @@ -32,6 +32,6 @@ class MultiPickerIncomingFiles @Inject constructor( fun media(intent: Intent) = MultiPicker.get(MultiPicker.MEDIA).getIncomingFiles(context, intent).map { it.toContentAttachmentData() } fun file(intent: Intent) = MultiPicker.get(MultiPicker.FILE).getIncomingFiles(context, intent).map { it.toContentAttachmentData() } - + fun audio(intent: Intent) = MultiPicker.get(MultiPicker.AUDIO).getIncomingFiles(context, intent).map { it.toContentAttachmentData() } } From 59ef8e10c8e649a8a2b9226cead1291e68416358 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Wed, 6 Jul 2022 12:02:45 +0100 Subject: [PATCH 3/4] injecting the context directly to the handler --- .../im/vector/app/features/attachments/ShareIntentHandler.kt | 3 ++- .../vector/app/features/home/room/detail/TimelineFragment.kt | 2 +- .../im/vector/app/features/share/IncomingShareFragment.kt | 1 - .../vector/app/features/attachments/ShareIntentHandlerTest.kt | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/attachments/ShareIntentHandler.kt b/vector/src/main/java/im/vector/app/features/attachments/ShareIntentHandler.kt index 8cd20d36c1..1d722c2341 100644 --- a/vector/src/main/java/im/vector/app/features/attachments/ShareIntentHandler.kt +++ b/vector/src/main/java/im/vector/app/features/attachments/ShareIntentHandler.kt @@ -23,6 +23,7 @@ import javax.inject.Inject class ShareIntentHandler @Inject constructor( private val multiPickerIncomingFiles: MultiPickerIncomingFiles, + private val context: Context, ) { /** @@ -30,7 +31,7 @@ class ShareIntentHandler @Inject constructor( * * @return true if it can handle the intent data, false otherwise */ - fun handleIncomingShareIntent(context: Context, intent: Intent, onFile: (List) -> Unit, onPlainText: (String) -> Unit): Boolean { + fun handleIncomingShareIntent(intent: Intent, onFile: (List) -> Unit, onPlainText: (String) -> Unit): Boolean { val type = intent.resolveType(context) ?: return false return when { type == "text/plain" -> handlePlainText(intent, onPlainText) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt index 9468af7726..a3eff137c8 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt @@ -1619,7 +1619,7 @@ class TimelineFragment @Inject constructor( private fun sendUri(uri: Uri): Boolean { val shareIntent = Intent(Intent.ACTION_SEND, uri) - val isHandled = shareIntentHandler.handleIncomingShareIntent(requireContext(), shareIntent, ::onContentAttachmentsReady, onPlainText = { + val isHandled = shareIntentHandler.handleIncomingShareIntent(shareIntent, ::onContentAttachmentsReady, onPlainText = { fatalError("Should not happen as we're generating a File based share Intent", vectorPreferences.failFast()) }) if (!isHandled) { diff --git a/vector/src/main/java/im/vector/app/features/share/IncomingShareFragment.kt b/vector/src/main/java/im/vector/app/features/share/IncomingShareFragment.kt index a113c8105d..3f8923dd68 100644 --- a/vector/src/main/java/im/vector/app/features/share/IncomingShareFragment.kt +++ b/vector/src/main/java/im/vector/app/features/share/IncomingShareFragment.kt @@ -116,7 +116,6 @@ class IncomingShareFragment @Inject constructor( } private fun handleIncomingShareIntent(intent: Intent) = shareIntentHandler.handleIncomingShareIntent( - requireContext(), intent, onFile = { val sharedData = SharedData.Attachments(it) diff --git a/vector/src/test/java/im/vector/app/features/attachments/ShareIntentHandlerTest.kt b/vector/src/test/java/im/vector/app/features/attachments/ShareIntentHandlerTest.kt index bb3aabf67f..d2fba95eee 100644 --- a/vector/src/test/java/im/vector/app/features/attachments/ShareIntentHandlerTest.kt +++ b/vector/src/test/java/im/vector/app/features/attachments/ShareIntentHandlerTest.kt @@ -36,7 +36,7 @@ class ShareIntentHandlerTest { private val onFile = FakeFunction1>() private val onPlainText = FakeFunction1() - private val shareIntentHandler = ShareIntentHandler(fakeMultiPickerIncomingFiles.instance) + private val shareIntentHandler = ShareIntentHandler(fakeMultiPickerIncomingFiles.instance, A_CONTEXT) @Test fun `given an unhandled sharing intent type, when handling intent, then is not handled`() { @@ -161,6 +161,6 @@ class ShareIntentHandlerTest { } private fun handleIncomingShareIntent(intent: FakeIntent): Boolean { - return shareIntentHandler.handleIncomingShareIntent(A_CONTEXT, intent.instance, onFile.capture, onPlainText.capture) + return shareIntentHandler.handleIncomingShareIntent(intent.instance, onFile.capture, onPlainText.capture) } } From 169ac9d0a08da3ad0acddaf74c013eb2733279f8 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Wed, 6 Jul 2022 12:06:17 +0100 Subject: [PATCH 4/4] updating the known SDK mimetypes and making use of them for the intent switches --- .../matrix/android/sdk/api/util/MimeTypes.kt | 6 ++++++ .../features/attachments/ShareIntentHandler.kt | 18 +++++++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MimeTypes.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MimeTypes.kt index ef47775f1b..5ec0dedadf 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MimeTypes.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MimeTypes.kt @@ -33,9 +33,15 @@ object MimeTypes { const val Ogg = "audio/ogg" + const val PlainText = "text/plain" + fun String?.normalizeMimeType() = if (this == BadJpg) Jpeg else this fun String?.isMimeTypeImage() = this?.startsWith("image/").orFalse() fun String?.isMimeTypeVideo() = this?.startsWith("video/").orFalse() fun String?.isMimeTypeAudio() = this?.startsWith("audio/").orFalse() + fun String?.isMimeTypeApplication() = this?.startsWith("application/").orFalse() + fun String?.isMimeTypeFile() = this?.startsWith("file/").orFalse() + fun String?.isMimeTypeText() = this?.startsWith("text/").orFalse() + fun String?.isMimeTypeAny() = this?.startsWith("*/").orFalse() } diff --git a/vector/src/main/java/im/vector/app/features/attachments/ShareIntentHandler.kt b/vector/src/main/java/im/vector/app/features/attachments/ShareIntentHandler.kt index 1d722c2341..18caba10d9 100644 --- a/vector/src/main/java/im/vector/app/features/attachments/ShareIntentHandler.kt +++ b/vector/src/main/java/im/vector/app/features/attachments/ShareIntentHandler.kt @@ -19,6 +19,14 @@ package im.vector.app.features.attachments import android.content.Context import android.content.Intent import org.matrix.android.sdk.api.session.content.ContentAttachmentData +import org.matrix.android.sdk.api.util.MimeTypes +import org.matrix.android.sdk.api.util.MimeTypes.isMimeTypeAny +import org.matrix.android.sdk.api.util.MimeTypes.isMimeTypeApplication +import org.matrix.android.sdk.api.util.MimeTypes.isMimeTypeAudio +import org.matrix.android.sdk.api.util.MimeTypes.isMimeTypeFile +import org.matrix.android.sdk.api.util.MimeTypes.isMimeTypeImage +import org.matrix.android.sdk.api.util.MimeTypes.isMimeTypeText +import org.matrix.android.sdk.api.util.MimeTypes.isMimeTypeVideo import javax.inject.Inject class ShareIntentHandler @Inject constructor( @@ -34,11 +42,11 @@ class ShareIntentHandler @Inject constructor( fun handleIncomingShareIntent(intent: Intent, onFile: (List) -> Unit, onPlainText: (String) -> Unit): Boolean { val type = intent.resolveType(context) ?: return false return when { - type == "text/plain" -> handlePlainText(intent, onPlainText) - type.startsWith("image") -> onFile(multiPickerIncomingFiles.image(intent)).let { true } - type.startsWith("video") -> onFile(multiPickerIncomingFiles.video(intent)).let { true } - type.startsWith("audio") -> onFile(multiPickerIncomingFiles.audio(intent)).let { true } - type.startsWith("application") || type.startsWith("file") || type.startsWith("text") || type.startsWith("*") -> { + type == MimeTypes.PlainText -> handlePlainText(intent, onPlainText) + type.isMimeTypeImage() -> onFile(multiPickerIncomingFiles.image(intent)).let { true } + type.isMimeTypeVideo() -> onFile(multiPickerIncomingFiles.video(intent)).let { true } + type.isMimeTypeAudio() -> onFile(multiPickerIncomingFiles.audio(intent)).let { true } + type.isMimeTypeApplication() || type.isMimeTypeFile() || type.isMimeTypeText() || type.isMimeTypeAny() -> { onFile(multiPickerIncomingFiles.file(intent)).let { true } } else -> false