Skip to content
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

Merged
merged 9 commits into from
Aug 13, 2019

Conversation

mzorz
Copy link
Contributor

@mzorz mzorz commented Aug 9, 2019

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 in openCamera 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 the openCamera() 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

@mzorz mzorz requested a review from aforcier August 9, 2019 15:24
@aforcier aforcier self-assigned this Aug 12, 2019
@aforcier aforcier added this to the Demo 1: Basic Creation milestone Aug 12, 2019
@@ -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) {
Copy link
Collaborator

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.)

Copy link
Contributor Author

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)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

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!!)) {
Copy link
Collaborator

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?

Copy link
Contributor Author

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 👍

Copy link
Contributor Author

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() {
Copy link
Collaborator

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for pointing that out - I moved this Dialog from a separate file into the PermissionUtils class and have plans for it as we tackle #15 - but we could be removing it entirely right now so, removed in fe7ee0d

@@ -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!!)
Copy link
Collaborator

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 ->
    ...
}

Copy link
Contributor Author

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 -> {
Copy link
Collaborator

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
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 da2e480

Copy link
Collaborator

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 falses aren't doing anything).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤕 🤦‍♂ fixed in 733f9d4

@aforcier
Copy link
Collaborator

Looks good @mzorz, left a few small comments 👍

@aforcier aforcier changed the base branch from app/foundation-add-mp4composer-kotlin to app/foundation August 12, 2019 21:49
@mzorz
Copy link
Contributor Author

mzorz commented Aug 13, 2019

Ready for another round @aforcier ! Thanks for your comments, made me look closer 🙇
Also worth noting, planning to further work on this in detail when we tackle #15

}
setUpCameraOutputs(width, height)
configureTransform(width, height)
val manager = activity!!.getSystemService(Context.CAMERA_SERVICE) as CameraManager
Copy link
Collaborator

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)

Copy link
Contributor Author

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

@aforcier
Copy link
Collaborator

Looks good! Two more small follow-ups: #22 (comment) and #22 (comment).

@aforcier
Copy link
Collaborator

:shipit:

@aforcier aforcier merged commit 9bf8692 into app/foundation Aug 13, 2019
@aforcier aforcier deleted the app/foundation-permissions-refactor branch August 13, 2019 19:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants