-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Simplified permission handling #22
Conversation
…esn't need to know when to request them
@@ -468,7 +454,7 @@ class Camera2BasicHandling : Fragment(), View.OnClickListener, | |||
private fun openCamera(width: Int, height: Int) { | |||
val permission = ContextCompat.checkSelfPermission(activity!!, Manifest.permission.CAMERA) | |||
if (permission != PackageManager.PERMISSION_GRANTED) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is tripped and we request permissions here, we'll get a crash:
Caused by: kotlin.UninitializedPropertyAccessException: lateinit property previewSize has not been initialized
at com.automattic.photoeditor.camera.Camera2BasicHandling.createCameraRecordingSession(Camera2BasicHandling.kt:779)
at com.automattic.photoeditor.state.BackgroundSurfaceManager.switchCameraPreviewOn(BackgroundSurfaceManager.kt:139)
at com.automattic.portkey.compose.ComposeLoopFrameActivity.onRequestPermissionsResult(ComposeLoopFrameActivity.kt:100)
at android.app.Activity.dispatchRequestPermissionsResult(Activity.java:7616)
at android.app.Activity.dispatchActivityResult(Activity.java:7466)
at android.app.ActivityThread.deliverResults(ActivityThread.java:4391)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4440)
at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:49)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1816)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6718)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
because in this case we're calling createCameraRecordingSession()
without having called setUpCameraOutputs()
first.
(Note that I triggered this by changing the code as a test - I'm not sure if we'd practically ever get to this point without permissions being already checked and granted.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Permissions are interesting, I also thought we could pretty much just ask for everything in the beginning, but users could modify things on the fly so, we should be checkin for the needed permissions every time (and request them if we find out they're not granted). This may mean a better refactor needs to be done - I think we can leave a proper analysis / optimization for later when we deal with #15
Manifest.permission.WRITE_EXTERNAL_STORAGE, | ||
Manifest.permission.CAMERA | ||
) | ||
PermissionUtils.requestPermissions(this, permissions) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this array here could be referenced from https://github.com/Automattic/portkey-android/pull/22/files#diff-17873655147830fd3d87310ec402fb49R21
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just mentioning it here as I'll probably change it in a future PR 👍 :)
FRAGMENT_DIALOG | ||
) | ||
} | ||
if (!PermissionUtils.allRequiredPermissionsGranted(activity!!)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure that this function (onRequestPermissionsResult()
) would ever get called, even if we did trigger a permissions request further down (which at the moment will cause a crash anyway). I believe we'd need to use Fragment.requestPermissions()
for that to happen, but we're actually using ActivityCompat.requestPermissions
, which will only trigger the host activity's callback function.
At least, I haven't been able to trigger it through testing. If my logic is sound maybe we can drop this entirely?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TIL that requesting permissions from the Fragment as opposed to requesting them from the Activity would make a difference - let's remove that piece of code for now, and we'll get back at reviewing permissions in a more holistic way in #15 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After testing for some time, removed this piece of code in e2fe8ee - noting here there's still some possibility of crashing due to other reasons when preview/recording start/stop state handling is not reflecting the actual current state as per backgroundSurfaceManager.switchCameraPreviewOn()
only keeps flags and assumes things are going to be ok. Deferring a refactor of that part for later, as it exceeds this PR.
} | ||
} | ||
|
||
class ConfirmationDialog : DialogFragment() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This appears to be unused at the moment, was that intentional?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -468,7 +454,7 @@ class Camera2BasicHandling : Fragment(), View.OnClickListener, | |||
private fun openCamera(width: Int, height: Int) { | |||
val permission = ContextCompat.checkSelfPermission(activity!!, Manifest.permission.CAMERA) | |||
if (permission != PackageManager.PERMISSION_GRANTED) { | |||
requestCameraPermission() | |||
PermissionUtils.requestAllRequiredPermissions(activity!!) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can get rid of the force unwrap !!
here and above and just wrap the whole body of this function in activity.let {}
:
activity?.let { activity ->
...
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 thanks for the observation, addressed in 16d9a41
grantResults[0] == PackageManager.PERMISSION_GRANTED, | ||
permissions[0] | ||
) | ||
PERMISSION_REQUEST_CODE -> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can lift the return
out here:
return when (requestCode) {
PERMISSION_REQUEST_CODE -> {
onRequestPermissionChecker.isPermissionGranted(
grantResults[0] == PackageManager.PERMISSION_GRANTED,
permissions[0]
)
true
}
else -> false
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 da2e480
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like you missed the return when
part, once you add that 20033ac isn't needed anymore (and I think at the moment the earlier true
and false
s aren't doing anything).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤕 🤦♂ fixed in 733f9d4
Looks good @mzorz, left a few small comments 👍 |
} | ||
setUpCameraOutputs(width, height) | ||
configureTransform(width, height) | ||
val manager = activity!!.getSystemService(Context.CAMERA_SERVICE) as CameraManager |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Forgot to remove the !!
here :D (it's now just unnecessary though, it's using the correct activity
that we know is not null)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah got it, fixed in c1b239e
Looks good! Two more small follow-ups: #22 (comment) and #22 (comment). |
Note: please review and merge #23 first :)
Permission handling was a bit here and there, now all required permissions are requested by the Activity (ComposeLoopFrameActivity) when the user requires the camera preview.
In
Camera2BasicHandling
we only care to re-request them if not available inopenCamera
as per a mandatory security warning (the user potentially could have revoked permissions in between, so we need to check for them). Could have avoided the check by adding a@SupressWarnings
annotation to theopenCamera()
method but decided it's safer to still re-check than to avoid warnings, as it's a potential cause of crash if we were to reuse things in the future and this piece of code would be used separately (for example, not contained by this specific Activity with the assumption it will request permissions for us).This is just some housework to keep things a bit cleaner, we'll get back at permissions handling once we get to actually work on #15