Skip to content

Missing permission requests for video and multi-image capture modes #402

@temcguir

Description

@temcguir

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:

        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:

        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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions