Thanks to visit codestin.com
Credit goes to github.com

Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

[camera] Adding check for null before creating capture session. #2965

Closed
wants to merge 1 commit into from

Conversation

panmari
Copy link
Contributor

@panmari panmari commented Aug 26, 2020

Description

Occasionally leads to NullPointerException (potentially due to some race
condition, hard to reproduce deterministically). This patch makes the error go away. I have an app in prod that has 0 occurences of this behavior after the patch. Example stack trace:

E/AndroidRuntime( 5679): java.lang.NullPointerException: Attempt to
invoke virtual method 'android.view.Surface
android.media.ImageReader.getSurface()' on a null object reference
E/AndroidRuntime( 5679): 	at
io.flutter.plugins.camera.Camera.startPreview(Camera.java:424)
E/AndroidRuntime( 5679): 	at
io.flutter.plugins.camera.Camera$2.onOpened(Camera.java:160)
E/AndroidRuntime( 5679): 	at
android.hardware.camera2.impl.CameraDeviceImpl$1.run(CameraDeviceImpl.java:145)
E/AndroidRuntime( 5679): 	at
android.os.Handler.handleCallback(Handler.java:883)
E/AndroidRuntime( 5679): 	at
android.os.Handler.dispatchMessage(Handler.java:100)
E/AndroidRuntime( 5679): 	at
android.os.Looper.loop(Looper.java:214)
E/AndroidRuntime( 5679): 	at
android.app.ActivityThread.main(ActivityThread.java:7356)
E/AndroidRuntime( 5679): 	at
java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime( 5679): 	at
com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
E/AndroidRuntime( 5679): 	at
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

Related Issues

Checklist

Before you create this PR confirm that it meets all requirements listed below by checking the relevant checkboxes ([x]). This will ensure a smooth and quick review process.

  • I read the [Contributor Guide] and followed the process outlined there for submitting PRs.
  • My PR includes unit or integration tests for all changed/updated/fixed behaviors (See [Contributor Guide]).
  • All existing and new tests are passing.
  • I updated/added relevant documentation (doc comments with ///).
  • The analyzer (flutter analyze) does not report any problems on my PR.
  • I read and followed the [Flutter Style Guide].
  • The title of the PR starts with the name of the plugin surrounded by square brackets, e.g. [shared_preferences]
  • I updated pubspec.yaml with an appropriate new version according to the [pub versioning philosophy].
  • I updated CHANGELOG.md to add a description of the change.
  • I signed the [CLA].
  • I am willing to follow-up on review comments in a timely manner.

Breaking Change

Does your PR require plugin users to manually update their apps to accommodate your change?

  • Yes, this is a breaking change (please indicate a breaking change in CHANGELOG.md and increment major revision).
  • No, this is not a breaking change.

@RenanDelfanti
Copy link

This pull request resolve my problem! Thanks!

@panmari
Copy link
Contributor Author

panmari commented Sep 8, 2020

Good to hear Renan!

@bparrishMines there is probably a nicer solution somewhere that solves the underlying issue, but how about we merge this CL for now as it fixes the symptoms?

@panmari
Copy link
Contributor Author

panmari commented Sep 12, 2020

Friendly bump for @bparrishMines :)

Occasionally leads to NullPointerException (potentially due to some race
condition, hard to reproduce deterministically). Example stack trace:

E/AndroidRuntime( 5679): java.lang.NullPointerException: Attempt to
invoke virtual method 'android.view.Surface
android.media.ImageReader.getSurface()' on a null object reference
E/AndroidRuntime( 5679): 	at
io.flutter.plugins.camera.Camera.startPreview(Camera.java:424)
E/AndroidRuntime( 5679): 	at
io.flutter.plugins.camera.Camera$2.onOpened(Camera.java:160)
E/AndroidRuntime( 5679): 	at
android.hardware.camera2.impl.CameraDeviceImpl$1.run(CameraDeviceImpl.java:145)
E/AndroidRuntime( 5679): 	at
android.os.Handler.handleCallback(Handler.java:883)
E/AndroidRuntime( 5679): 	at
android.os.Handler.dispatchMessage(Handler.java:100)
E/AndroidRuntime( 5679): 	at
android.os.Looper.loop(Looper.java:214)
E/AndroidRuntime( 5679): 	at
android.app.ActivityThread.main(ActivityThread.java:7356)
E/AndroidRuntime( 5679): 	at
java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime( 5679): 	at
com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
E/AndroidRuntime( 5679): 	at
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
@panmari
Copy link
Contributor Author

panmari commented Sep 20, 2020

Rebased again.

@bparrishMines
Copy link
Contributor

cc @mvanbeusekom

Copy link
Contributor

@mvanbeusekom mvanbeusekom left a comment

Choose a reason for hiding this comment

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

This need explanation if the pictureImageReader is allowed to be null when the startPreview method is called.

Comment on lines +424 to +426
if (pictureImageReader != null) {
createCaptureSession(CameraDevice.TEMPLATE_PREVIEW, pictureImageReader.getSurface());
}
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: you could invert the if statement to reduce nesting and would make it a bit easier to expand the method:

Suggested change
if (pictureImageReader != null) {
createCaptureSession(CameraDevice.TEMPLATE_PREVIEW, pictureImageReader.getSurface());
}
if (pictureImageReader == null) {
return;
}
createCaptureSession(CameraDevice.TEMPLATE_PREVIEW, pictureImageReader.getSurface());

Copy link
Contributor

@mvanbeusekom mvanbeusekom Sep 22, 2020

Choose a reason for hiding this comment

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

Looking further into this issue, it would be good to know why pictureImageReader is null at this point and if that is valid (as @tvolkert also mentioned in his comments on PR #2871 ).

If the pictureImageReader should not be null when startPreview is called, this code will hide a mistake that is somewhere else in the code. I will start looking into this.

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 Maurits for looking into this! I agree that this is only a workaround for a symptom, but not a proper fix. Do you have a hunch where the real problem could lie?

Copy link
Contributor

Choose a reason for hiding this comment

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

Hi @panmari, we (me and a colleague) have been looking into this issue and can't quite reproduce it as of yet. We do have 2 theories at the moment:

  1. Since version 0.5.0 developers are responsible for handling application lifecycle events that might affect the plugin (see also this comment mentioned by @kevin-lot). If these events are not handled correctly it might cause the issue where the permission system moves the app to the background and not reinitialize the camera plugin correctly (leaving it in an invalid state);
  2. We could did get the same error when (using the example app) very rapidly switching between the front and back facing cameras. We noticed that in these cases the onOpened callback would be called when the dispose method has already been run (race condition).

I am currently discussing on how we should approach these problems.

@panmari
Copy link
Contributor Author

panmari commented Oct 12, 2020

Abandoning in favor of #3127

@panmari panmari closed this Oct 12, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants