Skip to content
This repository has been archived by the owner on Nov 1, 2022. It is now read-only.

Closes issue #7983: Generate a file name when the content provider doesn't provide one. #8104

Merged
merged 1 commit into from
Aug 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@

package mozilla.components.browser.engine.gecko.prompt

import android.content.ContentResolver
import android.content.Context
import android.net.Uri
import android.provider.OpenableColumns
import androidx.annotation.VisibleForTesting
import mozilla.components.browser.engine.gecko.GeckoEngineSession
import mozilla.components.concept.storage.Login
Expand All @@ -18,7 +16,7 @@ import mozilla.components.concept.engine.prompt.PromptRequest.MultipleChoice
import mozilla.components.concept.engine.prompt.PromptRequest.SingleChoice
import mozilla.components.concept.engine.prompt.ShareData
import mozilla.components.support.base.log.logger.Logger
import mozilla.components.support.ktx.kotlin.sanitizeFileName
import mozilla.components.support.ktx.android.net.getFileName
import mozilla.components.support.ktx.kotlin.toDate
import org.mozilla.geckoview.AllowOrDeny
import org.mozilla.geckoview.GeckoResult
Expand All @@ -32,8 +30,10 @@ import org.mozilla.geckoview.GeckoSession.PromptDelegate.DateTimePrompt.Type.TIM
import org.mozilla.geckoview.GeckoSession.PromptDelegate.DateTimePrompt.Type.WEEK
import org.mozilla.geckoview.GeckoSession.PromptDelegate.PromptResponse
import org.mozilla.geckoview.Autocomplete
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.io.InputStream
import java.security.InvalidParameterException
import java.text.SimpleDateFormat
import java.util.Date
Expand Down Expand Up @@ -541,25 +541,19 @@ internal class GeckoPromptDelegate(private val geckoEngineSession: GeckoEngineSe
val temporalFile = java.io.File(cacheUploadDirectory, getFileName(contentResolver))
try {
contentResolver.openInputStream(this)!!.use { inStream ->
FileOutputStream(temporalFile).use { outStream ->
inStream.copyTo(outStream)
}
copyFile(temporalFile, inStream)
}
} catch (e: IOException) {
Logger("GeckoPromptDelegate").warn("Could not convert uri to file uri", e)
}
return Uri.parse("file:///${temporalFile.absolutePath}")
}

private fun Uri.getFileName(contentResolver: ContentResolver): String {
val returnUri = this
var fileName = ""
contentResolver.query(returnUri, null, null, null, null)?.use { cursor ->
val nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
cursor.moveToFirst()
fileName = cursor.getString(nameIndex)
@VisibleForTesting
internal fun copyFile(temporalFile: File, inStream: InputStream): Long {
return FileOutputStream(temporalFile).use { outStream ->
inStream.copyTo(outStream)
}
return fileName.sanitizeFileName()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import mozilla.components.concept.engine.prompt.PromptRequest
import mozilla.components.concept.engine.prompt.PromptRequest.MultipleChoice
import mozilla.components.concept.engine.prompt.PromptRequest.SingleChoice
import mozilla.components.support.ktx.kotlin.toDate
import mozilla.components.support.test.any
import mozilla.components.support.test.mock
import mozilla.components.support.test.robolectric.testContext
import mozilla.components.support.test.whenever
Expand All @@ -24,6 +25,8 @@ import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.spy
import org.mockito.Mockito.doReturn
import org.mozilla.gecko.util.GeckoBundle
import org.mozilla.geckoview.GeckoRuntime
import org.mozilla.geckoview.GeckoSession
Expand All @@ -35,7 +38,6 @@ import org.mozilla.geckoview.GeckoSession.PromptDelegate.DateTimePrompt.Type.WEE
import org.mozilla.geckoview.GeckoSession.PromptDelegate.FilePrompt.Capture.ANY
import org.mozilla.geckoview.GeckoSession.PromptDelegate.FilePrompt.Capture.NONE
import org.mozilla.geckoview.GeckoSession.PromptDelegate.FilePrompt.Capture.USER
import org.robolectric.Shadows.shadowOf
import java.io.FileInputStream
import java.security.InvalidParameterException
import java.util.Calendar
Expand Down Expand Up @@ -549,20 +551,24 @@ class GeckoPromptDelegateTest {

@Test
fun `Calling onFilePrompt must provide a FilePicker PromptRequest`() {
val context = testContext

val context = spy(testContext)
val contentResolver = spy(context.contentResolver)
val mockSession = GeckoEngineSession(runtime)
var onSingleFileSelectedWasCalled = false
var onMultipleFilesSelectedWasCalled = false
var onDismissWasCalled = false
val mockUri: Uri = mock()
val mockFileInput: FileInputStream = mock()
val shadowContentResolver = shadowOf(context.contentResolver)

shadowContentResolver.registerInputStream(mockUri, mockFileInput)
doReturn(contentResolver).`when`(context).contentResolver
doReturn(mock<FileInputStream>()).`when`(contentResolver).openInputStream(mozilla.components.support.test.any())

var filePickerRequest: PromptRequest.File = mock()

val promptDelegate = GeckoPromptDelegate(mockSession)
val promptDelegate = spy(GeckoPromptDelegate(mockSession))

// Prevent the file from being copied
doReturn(0L).`when`(promptDelegate).copyFile(any(), any())

mockSession.register(object : EngineSession.Observer {
override fun onPromptRequest(promptRequest: PromptRequest) {
filePickerRequest = promptRequest as PromptRequest.File
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@

package mozilla.components.browser.engine.gecko.prompt

import android.content.ContentResolver
import android.content.Context
import android.net.Uri
import android.provider.OpenableColumns
import androidx.annotation.VisibleForTesting
import mozilla.components.browser.engine.gecko.GeckoEngineSession
import mozilla.components.concept.storage.Login
Expand All @@ -18,7 +16,7 @@ import mozilla.components.concept.engine.prompt.PromptRequest.MultipleChoice
import mozilla.components.concept.engine.prompt.PromptRequest.SingleChoice
import mozilla.components.concept.engine.prompt.ShareData
import mozilla.components.support.base.log.logger.Logger
import mozilla.components.support.ktx.kotlin.sanitizeFileName
import mozilla.components.support.ktx.android.net.getFileName
import mozilla.components.support.ktx.kotlin.toDate
import org.mozilla.geckoview.AllowOrDeny
import org.mozilla.geckoview.GeckoResult
Expand All @@ -32,8 +30,10 @@ import org.mozilla.geckoview.GeckoSession.PromptDelegate.DateTimePrompt.Type.TIM
import org.mozilla.geckoview.GeckoSession.PromptDelegate.DateTimePrompt.Type.WEEK
import org.mozilla.geckoview.GeckoSession.PromptDelegate.PromptResponse
import org.mozilla.geckoview.Autocomplete
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.io.InputStream
import java.security.InvalidParameterException
import java.text.SimpleDateFormat
import java.util.Date
Expand Down Expand Up @@ -541,25 +541,19 @@ internal class GeckoPromptDelegate(private val geckoEngineSession: GeckoEngineSe
val temporalFile = java.io.File(cacheUploadDirectory, getFileName(contentResolver))
try {
contentResolver.openInputStream(this)!!.use { inStream ->
FileOutputStream(temporalFile).use { outStream ->
inStream.copyTo(outStream)
}
copyFile(temporalFile, inStream)
}
} catch (e: IOException) {
Logger("GeckoPromptDelegate").warn("Could not convert uri to file uri", e)
}
return Uri.parse("file:///${temporalFile.absolutePath}")
}

private fun Uri.getFileName(contentResolver: ContentResolver): String {
val returnUri = this
var fileName = ""
contentResolver.query(returnUri, null, null, null, null)?.use { cursor ->
val nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
cursor.moveToFirst()
fileName = cursor.getString(nameIndex)
@VisibleForTesting
internal fun copyFile(temporalFile: File, inStream: InputStream): Long {
return FileOutputStream(temporalFile).use { outStream ->
inStream.copyTo(outStream)
}
return fileName.sanitizeFileName()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import mozilla.components.concept.engine.prompt.PromptRequest
import mozilla.components.concept.engine.prompt.PromptRequest.MultipleChoice
import mozilla.components.concept.engine.prompt.PromptRequest.SingleChoice
import mozilla.components.support.ktx.kotlin.toDate
import mozilla.components.support.test.any
import mozilla.components.support.test.mock
import mozilla.components.support.test.robolectric.testContext
import mozilla.components.support.test.whenever
Expand All @@ -24,6 +25,8 @@ import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.spy
import org.mockito.Mockito.doReturn
import org.mozilla.gecko.util.GeckoBundle
import org.mozilla.geckoview.GeckoRuntime
import org.mozilla.geckoview.GeckoSession
Expand All @@ -35,7 +38,6 @@ import org.mozilla.geckoview.GeckoSession.PromptDelegate.DateTimePrompt.Type.WEE
import org.mozilla.geckoview.GeckoSession.PromptDelegate.FilePrompt.Capture.ANY
import org.mozilla.geckoview.GeckoSession.PromptDelegate.FilePrompt.Capture.NONE
import org.mozilla.geckoview.GeckoSession.PromptDelegate.FilePrompt.Capture.USER
import org.robolectric.Shadows.shadowOf
import java.io.FileInputStream
import java.security.InvalidParameterException
import java.util.Calendar
Expand Down Expand Up @@ -549,20 +551,24 @@ class GeckoPromptDelegateTest {

@Test
fun `Calling onFilePrompt must provide a FilePicker PromptRequest`() {
val context = testContext

val context = spy(testContext)
val contentResolver = spy(context.contentResolver)
val mockSession = GeckoEngineSession(runtime)
var onSingleFileSelectedWasCalled = false
var onMultipleFilesSelectedWasCalled = false
var onDismissWasCalled = false
val mockUri: Uri = mock()
val mockFileInput: FileInputStream = mock()
val shadowContentResolver = shadowOf(context.contentResolver)

shadowContentResolver.registerInputStream(mockUri, mockFileInput)
doReturn(contentResolver).`when`(context).contentResolver
doReturn(mock<FileInputStream>()).`when`(contentResolver).openInputStream(any())

var filePickerRequest: PromptRequest.File = mock()

val promptDelegate = GeckoPromptDelegate(mockSession)
val promptDelegate = spy(GeckoPromptDelegate(mockSession))

// Prevent the file from being copied
doReturn(0L).`when`(promptDelegate).copyFile(any(), any())

mockSession.register(object : EngineSession.Observer {
override fun onPromptRequest(promptRequest: PromptRequest) {
filePickerRequest = promptRequest as PromptRequest.File
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@

package mozilla.components.browser.engine.gecko.prompt

import android.content.ContentResolver
import android.content.Context
import android.net.Uri
import android.provider.OpenableColumns
import androidx.annotation.VisibleForTesting
import mozilla.components.browser.engine.gecko.GeckoEngineSession
import mozilla.components.concept.storage.Login
Expand All @@ -18,7 +16,7 @@ import mozilla.components.concept.engine.prompt.PromptRequest.MultipleChoice
import mozilla.components.concept.engine.prompt.PromptRequest.SingleChoice
import mozilla.components.concept.engine.prompt.ShareData
import mozilla.components.support.base.log.logger.Logger
import mozilla.components.support.ktx.kotlin.sanitizeFileName
import mozilla.components.support.ktx.android.net.getFileName
import mozilla.components.support.ktx.kotlin.toDate
import org.mozilla.geckoview.AllowOrDeny
import org.mozilla.geckoview.GeckoResult
Expand All @@ -32,8 +30,10 @@ import org.mozilla.geckoview.GeckoSession.PromptDelegate.DateTimePrompt.Type.TIM
import org.mozilla.geckoview.GeckoSession.PromptDelegate.DateTimePrompt.Type.WEEK
import org.mozilla.geckoview.GeckoSession.PromptDelegate.PromptResponse
import org.mozilla.geckoview.Autocomplete
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.io.InputStream
import java.security.InvalidParameterException
import java.text.SimpleDateFormat
import java.util.Date
Expand Down Expand Up @@ -541,25 +541,19 @@ internal class GeckoPromptDelegate(private val geckoEngineSession: GeckoEngineSe
val temporalFile = java.io.File(cacheUploadDirectory, getFileName(contentResolver))
try {
contentResolver.openInputStream(this)!!.use { inStream ->
FileOutputStream(temporalFile).use { outStream ->
inStream.copyTo(outStream)
}
copyFile(temporalFile, inStream)
}
} catch (e: IOException) {
Logger("GeckoPromptDelegate").warn("Could not convert uri to file uri", e)
}
return Uri.parse("file:///${temporalFile.absolutePath}")
}

private fun Uri.getFileName(contentResolver: ContentResolver): String {
val returnUri = this
var fileName = ""
contentResolver.query(returnUri, null, null, null, null)?.use { cursor ->
val nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
cursor.moveToFirst()
fileName = cursor.getString(nameIndex)
@VisibleForTesting
internal fun copyFile(temporalFile: File, inStream: InputStream): Long {
return FileOutputStream(temporalFile).use { outStream ->
inStream.copyTo(outStream)
}
return fileName.sanitizeFileName()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import mozilla.components.concept.engine.prompt.PromptRequest
import mozilla.components.concept.engine.prompt.PromptRequest.MultipleChoice
import mozilla.components.concept.engine.prompt.PromptRequest.SingleChoice
import mozilla.components.support.ktx.kotlin.toDate
import mozilla.components.support.test.any
import mozilla.components.support.test.mock
import mozilla.components.support.test.robolectric.testContext
import mozilla.components.support.test.whenever
Expand All @@ -24,6 +25,8 @@ import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.spy
import org.mockito.Mockito.doReturn
import org.mozilla.gecko.util.GeckoBundle
import org.mozilla.geckoview.GeckoRuntime
import org.mozilla.geckoview.GeckoSession
Expand All @@ -35,7 +38,6 @@ import org.mozilla.geckoview.GeckoSession.PromptDelegate.DateTimePrompt.Type.WEE
import org.mozilla.geckoview.GeckoSession.PromptDelegate.FilePrompt.Capture.ANY
import org.mozilla.geckoview.GeckoSession.PromptDelegate.FilePrompt.Capture.NONE
import org.mozilla.geckoview.GeckoSession.PromptDelegate.FilePrompt.Capture.USER
import org.robolectric.Shadows.shadowOf
import java.io.FileInputStream
import java.security.InvalidParameterException
import java.util.Calendar
Expand Down Expand Up @@ -549,20 +551,23 @@ class GeckoPromptDelegateTest {

@Test
fun `Calling onFilePrompt must provide a FilePicker PromptRequest`() {
val context = testContext

val context = spy(testContext)
val contentResolver = spy(context.contentResolver)
val mockSession = GeckoEngineSession(runtime)
var onSingleFileSelectedWasCalled = false
var onMultipleFilesSelectedWasCalled = false
var onDismissWasCalled = false
val mockUri: Uri = mock()
val mockFileInput: FileInputStream = mock()
val shadowContentResolver = shadowOf(context.contentResolver)

shadowContentResolver.registerInputStream(mockUri, mockFileInput)
doReturn(contentResolver).`when`(context).contentResolver
doReturn(mock<FileInputStream>()).`when`(contentResolver).openInputStream(any())
var filePickerRequest: PromptRequest.File = mock()

val promptDelegate = GeckoPromptDelegate(mockSession)
val promptDelegate = spy(GeckoPromptDelegate(mockSession))

// Prevent the file from being copied
doReturn(0L).`when`(promptDelegate).copyFile(any(), any())

mockSession.register(object : EngineSession.Observer {
override fun onPromptRequest(promptRequest: PromptRequest) {
filePickerRequest = promptRequest as PromptRequest.File
Expand Down
Loading