Skip to content

Commit

Permalink
fix(camera): Request only the permissions needed by Android version (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
jcesarmobile authored Aug 3, 2023
1 parent 658d3b6 commit f1585d6
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 8 deletions.
8 changes: 8 additions & 0 deletions camera/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ This API requires the following permissions be added to your `AndroidManifest.xm
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
```

You can also specify those permissions only for the Android versions where they will be requested:

```xml
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="29"/>
```

The storage permissions are for reading/saving photo files.

Read about [Setting Permissions](https://capacitorjs.com/docs/android/configuration#setting-permissions) in the [Android Guide](https://capacitorjs.com/docs/android) for more information on setting Android permissions.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,19 @@
name = "Camera",
permissions = {
@Permission(strings = { Manifest.permission.CAMERA }, alias = CameraPlugin.CAMERA),
// SDK VERSIONS 32 AND BELOW
// SDK VERSIONS 29 AND BELOW
@Permission(
strings = { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE },
alias = CameraPlugin.PHOTOS
),
/*
SDK VERSIONS 30-32
This alias is a placeholder and the PHOTOS alias will be updated to use this permission
so that the end user does not need to explicitly use separate aliases depending
on the SDK version.
*/
@Permission(strings = { Manifest.permission.READ_EXTERNAL_STORAGE }, alias = CameraPlugin.READ_EXTERNAL_STORAGE),
/*
SDK VERSIONS 33 AND ABOVE
This alias is a placeholder and the PHOTOS alias will be updated to use these permissions
so that the end user does not need to explicitly use separate aliases depending
Expand All @@ -82,6 +89,7 @@ public class CameraPlugin extends Plugin {
static final String CAMERA = "camera";
static final String PHOTOS = "photos";
static final String MEDIA = "media";
static final String READ_EXTERNAL_STORAGE = "readExternalStorage";

// Message constants
private static final String INVALID_RESULT_TYPE_ERROR = "Invalid resultType option";
Expand Down Expand Up @@ -206,11 +214,16 @@ else if (!hasCameraPerms) {
}

private boolean checkPhotosPermissions(PluginCall call) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
if (getPermissionState(PHOTOS) != PermissionState.GRANTED) {
requestPermissionForAlias(PHOTOS, call, "cameraPermissionsCallback");
return false;
}
} else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
if (getPermissionState(READ_EXTERNAL_STORAGE) != PermissionState.GRANTED) {
requestPermissionForAlias(READ_EXTERNAL_STORAGE, call, "cameraPermissionsCallback");
return false;
}
} else if (getPermissionState(MEDIA) != PermissionState.GRANTED) {
requestPermissionForAlias(MEDIA, call, "cameraPermissionsCallback");
return false;
Expand All @@ -235,9 +248,13 @@ private void cameraPermissionsCallback(PluginCall call) {
call.reject(PERMISSION_DENIED_ERROR_CAMERA);
return;
} else if (settings.getSource() == CameraSource.PHOTOS) {
PermissionState permissionState = (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU)
? getPermissionState(PHOTOS)
: getPermissionState(MEDIA);
String alias = MEDIA;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
alias = PHOTOS;
} else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
alias = READ_EXTERNAL_STORAGE;
}
PermissionState permissionState = getPermissionState(alias);
if (permissionState != PermissionState.GRANTED) {
Logger.debug(getLogTag(), "User denied photos permission: " + permissionState.toString());
call.reject(PERMISSION_DENIED_ERROR_PHOTOS);
Expand All @@ -257,6 +274,12 @@ protected void requestPermissionForAliases(@NonNull String[] aliases, @NonNull P
aliases[i] = MEDIA;
}
}
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
for (int i = 0; i < aliases.length; i++) {
if (aliases[i].equals(PHOTOS)) {
aliases[i] = READ_EXTERNAL_STORAGE;
}
}
}
super.requestPermissionForAliases(aliases, call, callbackName);
}
Expand Down Expand Up @@ -817,9 +840,15 @@ public Map<String, PermissionState> getPermissionStates() {
permissionStates.put(CAMERA, PermissionState.GRANTED);
}

// If the SDK version is 33 or higher, update the PHOTOS state to match the MEDIA state.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && permissionStates.containsKey(MEDIA)) {
permissionStates.put(PHOTOS, permissionStates.get(MEDIA));
// If the SDK version is 30 or higher, update the PHOTOS state to match the MEDIA or READ_EXTERNAL_STORAGE states.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
String alias = READ_EXTERNAL_STORAGE;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
alias = MEDIA;
}
if (permissionStates.containsKey(alias)) {
permissionStates.put(PHOTOS, permissionStates.get(alias));
}
}

return permissionStates;
Expand Down

0 comments on commit f1585d6

Please sign in to comment.