google / google/jetpack-camera-app

Missing permission requests for video and multi-image capture modes

Open
#402 0 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Kotlin
Stars
341
Forks
71
Avg merge
4d 17h
Merged PRs (30d)
7

Description

**Description:**

The permission handling logic in `JcaApp.kt` does not correctly request all necessary permissions for certain capture scenarios.
Specifically:
1. The `RECORD_AUDIO` permission is only requested when the `ExternalCaptureMode` is `Standard`, but it is also required when capturing video in other modes.
2. The `WRITE_EXTERNAL_STORAGE` permission is only requested for `Standard` mode on Android P and below.
However, it is also needed in `ExternalCaptureMode.MultipleImageCapture` mode when no output URIs are provided by the calling intent, forcing the app to save to the public gallery.

This can lead to crashes or unexpected behavior when the app attempts to record video or save multiple images without the required permissions.

**Analysis:**

The `JetpackCameraNavHost` composable in `JcaApp.kt` has the following logic for building the list of permissions to request:

```kotlin
val requestablePermissions = buildList {
add(android.Manifest.permission.CAMERA)
if (externalCaptureMode == ExternalCaptureMode.Standard) {
add(android.Manifest.permission.RECORD_AUDIO)
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
add(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
}
}
}
```

This code only considers the `Standard` capture mode.

1. **Audio Permission:** When the app is in a video capture mode (e.g. launched via `MediaStore.INTENT_ACTION_VIDEO_CAMERA`), it needs
`RECORD_AUDIO` permission, but the current logic does not request it.
2. **Storage Permission:** As determined from the logic in `MainActivity.kt`, when using `ExternalCaptureMode.MultipleImageCapture`, if the `MediaStore.EXTRA_OUTPUT` intent extra is missing, the app defaults to saving in the public gallery. This
action requires `WRITE_EXTERNAL_STORAGE` on older API levels, but the permission is not requested in this case.

**Suggested Fix:**

The permission request logic in `JcaApp.kt` should be updated to account for all capture modes and their specific requirements. The set of required permissions should be determined based
on the capture mode and the provided intent extras.

Here is a suggested implementation:

```kotlin
val requestablePermissions = buildList {
add(android.Manifest.permission.CAMERA)

// Add audio permission if in a mode that can record video.
// Assuming a Video mode exists for ExternalCaptureMode
if (externalCaptureMode == ExternalCaptureMode.Standard || externalCaptureMode == ExternalCaptureMode.Video) {
add(android.Manifest.permission.RECORD_AUDIO)
}

// Add storage permission for specific legacy cases
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
if (externalCaptureMode == ExternalCaptureMode.Standard) {
add(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
}
// Required for saving to public gallery in multi-image mode without URIs
if (externalCaptureMode is ExternalCaptureMode.MultipleImageCapture &&
captureUris.isEmpty()
) {
add(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
}
}
}
```

This change ensures that:

- `RECORD_AUDIO` is requested whenever video capture is possible.
- `WRITE_EXTERNAL_STORAGE` is requested on Android P and below when in `Standard` mode OR when in `MultipleImageCapture` mode without pre-supplied output
URIs.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.