Skip to content

Commit

Permalink
For mozilla-mobile#9351 - Get camera image even with "Don't keep acti…
Browse files Browse the repository at this point in the history
…vities"

The previous functionality was already based on saving the camera photo in a
specific file and then us reading it from there but what that file name was was
lost in the case of the activity being destroyed as being the case with "Don't
keep activities".
By making that file name top level it will now be available for the entire
duration of the app.
  • Loading branch information
Mugurell authored and mergify[bot] committed Jan 13, 2021
1 parent b992625 commit 00ce4bd
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@ import mozilla.components.support.base.log.logger.Logger
import mozilla.components.support.ktx.android.content.isPermissionGranted
import mozilla.components.support.ktx.android.net.isUnderPrivateAppDirectory

/**
* The image capture intent doesn't return the URI where the image is saved,
* so we track it here.
*
* Top-level scoped to survive activity recreation in the "Don't keep activities" scenario.
*/
@VisibleForTesting
internal var captureUri: Uri? = null

/**
* @property container The [Activity] or [Fragment] which hosts the file picker.
* @property store The [BrowserStore] this feature should subscribe to.
Expand All @@ -43,12 +52,6 @@ internal class FilePicker(

private val logger = Logger("FilePicker")

/**
* The image capture intent doesn't return the URI where the image is saved,
* so we track it here.
*/
private var captureUri: Uri? = null

/**
* Cache of the current request to be used after permission is granted.
*/
Expand Down Expand Up @@ -197,6 +200,8 @@ internal class FilePicker(
}
} ?: request.onDismiss()
}

captureUri = null
}

private fun saveCaptureUriIfPresent(intent: Intent) =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import android.content.Intent
import android.content.pm.PackageManager.PERMISSION_DENIED
import android.content.pm.PackageManager.PERMISSION_GRANTED
import android.net.Uri
import androidx.core.net.toUri
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import mozilla.components.browser.state.action.ContentAction
Expand All @@ -28,10 +29,12 @@ import mozilla.components.support.test.any
import mozilla.components.support.test.eq
import mozilla.components.support.test.mock
import mozilla.components.support.test.robolectric.grantPermission
import mozilla.components.support.test.robolectric.testContext
import mozilla.components.support.test.whenever
import org.junit.Assert.assertArrayEquals
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNull
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
Expand All @@ -42,6 +45,7 @@ import org.mockito.Mockito.never
import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyZeroInteractions
import java.io.File

@RunWith(AndroidJUnit4::class)
class FilePickerTest {
Expand Down Expand Up @@ -282,6 +286,70 @@ class FilePickerTest {
assertArrayEquals(permissions.toTypedArray(), permissionsRequested)
}

@Test
fun `handleFilePickerIntentResult called with null Intent will make captureUri null`() {
stubContext()
captureUri = "randomSaveLocationOnDisk".toUri()
val onSingleFileSelection: (Context, Uri) -> Unit = { _, _ -> Unit }
val promptRequest = mock<PromptRequest.File>()
doReturn(onSingleFileSelection).`when`(promptRequest).onSingleFileSelected

filePicker.handleFilePickerIntentResult(null, promptRequest)

assertNull(captureUri)
}

@Test
fun `handleFilePickerIntentResult called with valid Intent will make captureUri null also if request is dismissed`() {
stubContext()
captureUri = "randomSaveLocationOnDisk".toUri()
val promptRequest = mock<PromptRequest.File>()
doReturn({ }).`when`(promptRequest).onDismiss
// A private file cannot be picked so the request will be dismissed.
val intent = Intent().apply {
data = ("file://" + File(testContext.applicationInfo.dataDir, "randomFile").canonicalPath).toUri()
}

filePicker.handleFilePickerIntentResult(intent, promptRequest)

assertNull(captureUri)
}

@Test
fun `handleFilePickerIntentResult for multiple files selection will make captureUri null`() {
stubContext()
captureUri = "randomSaveLocationOnDisk".toUri()
val onMultipleFilesSelected: (Context, Array<Uri>) -> Unit = { _, _ -> Unit }
val promptRequest = mock<PromptRequest.File>()
doReturn(onMultipleFilesSelected).`when`(promptRequest).onMultipleFilesSelected
doReturn(true).`when`(promptRequest).isMultipleFilesSelection
val intent = Intent().apply {
clipData = (ClipData.newRawUri("Test", "https://www.mozilla.org".toUri()))
}

filePicker.handleFilePickerIntentResult(intent, promptRequest)

assertNull(captureUri)
}

@Test
fun `handleFilePickerIntentResult for multiple files selection will make captureUri null also if request is dismissed`() {
stubContext()
captureUri = "randomSaveLocationOnDisk".toUri()
val promptRequest = mock<PromptRequest.File>()
doReturn({ }).`when`(promptRequest).onDismiss
doReturn(true).`when`(promptRequest).isMultipleFilesSelection
// A private file cannot be picked so the request will be dismissed.
val intent = Intent().apply {
clipData = (ClipData.newRawUri("Test",
("file://" + File(testContext.applicationInfo.dataDir, "randomFile").canonicalPath).toUri()))
}

filePicker.handleFilePickerIntentResult(intent, promptRequest)

assertNull(captureUri)
}

private fun prepareSelectedSession(request: PromptRequest? = null): TabSessionState {
val promptRequest: PromptRequest = request ?: mock()
val content: ContentState = mock()
Expand Down
3 changes: 3 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ permalink: /changelog/
* [Gecko](https://github.com/mozilla-mobile/android-components/blob/master/buildSrc/src/main/java/Gecko.kt)
* [Configuration](https://github.com/mozilla-mobile/android-components/blob/master/.config.yml)

* **feature-prompts**:
* 🚒 Bug fixed [issue #9351] Camera images are available even with "Don't keep activities" enabled.

* **ui-autocomplete**:
* Pasting from the clipboard now cleans up any unwanted uri schemes.

Expand Down

0 comments on commit 00ce4bd

Please sign in to comment.