Skip to content

Commit

Permalink
camera:basic: fail if permissions are not granted
Browse files Browse the repository at this point in the history
Pre-work for #1031. For
some reason the UI for the storage permission isn't shown whenever
targetSdkVersion is 33+, and it's just returning a denial. This sample
is badly structured such that if either permission isn't granted, the UI
init will never run. The two permissions requests really ought to be
decoupled (the viewfinder should still work even if I never try to save
a photo), and the UI should tell the user why it failed. For now I'm
just making it fail more violently, because the lack of any error or
logging is what made this a multi-hour debugging experience instead of
the now obvious problem.
  • Loading branch information
DanAlbert committed May 14, 2024
1 parent fe5495d commit c2fa4af
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 10 deletions.
6 changes: 3 additions & 3 deletions camera/basic/src/main/cpp/camera_ui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,9 @@ void CameraEngine::OnPhotoTaken(const char *fileName) {
void CameraEngine::OnCameraPermission(jboolean granted) {
cameraGranted_ = (granted != JNI_FALSE);

if (cameraGranted_) {
OnAppInitWindow();
}
// TODO: Fail gracefully.
ASSERT(cameraGranted_, "required app permissions were not granted");
OnAppInitWindow();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@

import static android.hardware.camera2.CameraMetadata.LENS_FACING_BACK;

import java.util.Arrays;

class CameraSeekBar {
int _progress;
long _min, _max, _absVal;
Expand Down Expand Up @@ -212,19 +214,53 @@ public void RequestCamera() {
public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions,
@NonNull int[] grantResults) {
/*
* if any permission failed, the sample could not play
*/
if (PERMISSION_REQUEST_CODE_CAMERA != requestCode) {
if (requestCode != PERMISSION_REQUEST_CODE_CAMERA) {
// The permissions request isn't ours.
super.onRequestPermissionsResult(requestCode,
permissions,
grantResults);
return;
}

if(grantResults.length == 2) {
notifyCameraPermission(grantResults[0] == PackageManager.PERMISSION_GRANTED &&
grantResults[1] == PackageManager.PERMISSION_GRANTED);
if (permissions.length == 0) {
// https://developer.android.com/reference/androidx/core/app/ActivityCompat.OnRequestPermissionsResultCallback#onRequestPermissionsResult(int,java.lang.String[],int[])
//
// Note: It is possible that the permissions request interaction with the user is
// interrupted. In this case you will receive empty permissions and results arrays which
// should be treated as a cancellation.
//
// The docs aren't clear about *why* it might be canceled, so it's not clear what we
// should do here other than restart the request.
RequestCamera();
return;
}

boolean granted = Arrays.stream(grantResults)
.allMatch(element -> element == PackageManager.PERMISSION_GRANTED);
if (!granted) {
logDeniedPermissions(permissions, grantResults);
}
notifyCameraPermission(granted);
}

private void logDeniedPermissions(
@NonNull String[] requestedPermissions,
@NonNull int[] grantResults
) {
if (requestedPermissions.length != grantResults.length) {
throw new IllegalArgumentException(
String.format(
"requestedPermissions.length (%d) != grantResults.length (%d)",
requestedPermissions.length,
grantResults.length
)
);
}

for (int i = 0; i < requestedPermissions.length; i++) {
if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
Log.i(DBG_TAG, requestedPermissions[i] + " DENIED");
}
}
}

Expand Down

0 comments on commit c2fa4af

Please sign in to comment.