Skip to content

Commit

Permalink
Closes issue mozilla-mobile#7983: Generate a file name when the conte…
Browse files Browse the repository at this point in the history
…nt provider doesn't provide one.
  • Loading branch information
Amejia481 committed Aug 13, 2020
1 parent 147bfed commit a1cd163
Show file tree
Hide file tree
Showing 9 changed files with 247 additions and 63 deletions.
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

0 comments on commit a1cd163

Please sign in to comment.