Commit b9d83b82 authored by Arturo Mejia's avatar Arturo Mejia
Browse files

Closes #3227: Support file requests that contain files extensions types

 as a filter.
parent a3ff0215
Loading
Loading
Loading
Loading
+15 −3
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import mozilla.components.support.base.feature.LifecycleAwareFeature
import mozilla.components.support.ktx.android.content.isPermissionGranted
import java.security.InvalidParameterException
import java.util.Date
import android.webkit.MimeTypeMap

@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
internal const val FRAGMENT_TAG = "mozac_feature_prompt_dialog"
@@ -373,18 +374,29 @@ class PromptFeature(
        }
    }

    internal fun buildFileChooserIntent(allowMultipleSelection: Boolean, mimeTypes: Array<out String>): Intent {
    internal fun buildFileChooserIntent(allowMultipleSelection: Boolean, types: Array<out String>): Intent {
        return with(Intent(Intent.ACTION_GET_CONTENT)) {
            type = "*/*"
            addCategory(Intent.CATEGORY_OPENABLE)
            putExtra(Intent.EXTRA_LOCAL_ONLY, true)
            if (mimeTypes.isNotEmpty()) {
                putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes)
            if (types.isNotEmpty()) {
                putExtra(Intent.EXTRA_MIME_TYPES, convertFileExtensionsToMimeTypesIfNeeded(types))
            }
            putExtra(Intent.EXTRA_ALLOW_MULTIPLE, allowMultipleSelection)
        }
    }

    private fun convertFileExtensionsToMimeTypesIfNeeded(types: Array<out String>): Array<out String> {
        val mimeTypeMap = MimeTypeMap.getSingleton()
        return types.map { type ->
            if (type.contains("/")) {
                type
            } else {
                mimeTypeMap.getMimeTypeFromExtension(type) ?: "*/*"
            }
        }.toTypedArray()
    }

    @Suppress("ComplexMethod")
    @VisibleForTesting(otherwise = PRIVATE)
    internal fun handleDialogsRequest(
+27 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ import android.content.Intent.EXTRA_MIME_TYPES
import android.content.pm.PackageManager.PERMISSION_DENIED
import android.content.pm.PackageManager.PERMISSION_GRANTED
import android.net.Uri
import android.webkit.MimeTypeMap
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentTransaction
@@ -54,6 +55,7 @@ import org.mockito.Mockito.never
import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
import org.robolectric.RobolectricTestRunner
import org.robolectric.Shadows.shadowOf
import java.security.InvalidParameterException
import java.util.Date
import java.util.UUID
@@ -590,6 +592,31 @@ class PromptFeatureTest {
        }
    }

    @Test
    fun `buildFileChooserIntent with files extension types must produce an intent with the correct mime types`() {
        val shadowMimeTypeMap = shadowOf(MimeTypeMap.getSingleton())
        shadowMimeTypeMap.addExtensionMimeTypMapping(".gif", "image/gif")
        shadowMimeTypeMap.addExtensionMimeTypMapping(
            "docx",
            "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
        )

        promptFeature = PromptFeature(null, mock(), mockSessionManager, null, mockFragmentManager) { }

        val intent = promptFeature.buildFileChooserIntent(true, arrayOf(".gif", "image/jpeg", "docx", ".fun"))

        with(intent) {

            assertEquals(action, ACTION_GET_CONTENT)

            val mimeTypes = extras!!.get(EXTRA_MIME_TYPES) as Array<*>
            assertEquals(mimeTypes[0], "image/gif")
            assertEquals(mimeTypes[1], "image/jpeg")
            assertEquals(mimeTypes[2], "application/vnd.openxmlformats-officedocument.wordprocessingml.document")
            assertEquals(mimeTypes[3], "*/*")
        }
    }

    @Test
    fun `onPermissionsGranted will forward its call to onPromptRequested`() {
        val filePickerRequest = PromptRequest.File(emptyArray(), false, { _, _ -> }, { _, _ -> }) {}