Skip to content

[camera] Guard CameraController value updates after dispose#11861

Merged
auto-submit[bot] merged 3 commits into
flutter:mainfrom
motucraft:fix/camera-controller-update-after-dispose
Jul 13, 2026
Merged

[camera] Guard CameraController value updates after dispose#11861
auto-submit[bot] merged 3 commits into
flutter:mainfrom
motucraft:fix/camera-controller-update-after-dispose

Conversation

@motucraft

@motucraft motucraft commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Guards the value assignments in _initializeWithDescription so they no longer run after dispose(), fixing the "A CameraController was used after being disposed." crash.

These user-level steps, using the reproduction app in flutter/flutter#184959, trigger the crash:

  1. Open camera A.
  2. Close it before initialization finished (disposing the controller).
  3. Open camera B.
  4. Adjust an exposure/zoom slider.

When the controller is disposed while initialization is still in flight, the deferred value updates could call notifyListeners() on a disposed ChangeNotifier, throwing the exception above.
This adds if (!_isDisposed) guards (and awaits the initialization event only once) so those updates are skipped after dispose.
The guard lives in shared Dart code, so it also covers iOS and web.

Part of flutter/flutter#184959.

This PR addresses only the Dart-layer crash. As @mbcorona noted in flutter/flutter#184959 (comment), the ANR observed on Android has a separate native root cause (ImageReader not severing the stream on dispose, "BufferQueue has been abandoned"), which was routed to team-android. That native issue is not addressed here and should be handled separately in camera_android_camerax.

Pre-Review Checklist

If you need help, consider asking for advice on the #hackers-new channel on Discord.

Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the gemini-code-assist bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.

Footnotes

  1. Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling. 2

@google-cla

google-cla Bot commented Jun 8, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@motucraft motucraft force-pushed the fix/camera-controller-update-after-dispose branch 2 times, most recently from 021bc1c to 498851b Compare June 9, 2026 02:03
@motucraft motucraft marked this pull request as ready for review June 9, 2026 02:47

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request prevents CameraController from updating its value after being disposed by adding _isDisposed checks in the device orientation listener, the camera error listener, and after awaiting initialization. It also includes corresponding unit tests and bumps the package version to 0.12.1. Feedback suggests cancelling and nullifying _deviceOrientationSubscription in the PlatformException catch block of _initializeWithDescription to prevent resource leaks and ensure successful retries.

Comment on lines 385 to 386
} on PlatformException catch (e) {
throw CameraException(e.code, e.message);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

If _initializeWithDescription fails with a PlatformException, the _deviceOrientationSubscription that was created at the start of the method is left active and is never cancelled. This leads to a resource leak, and also prevents the subscription from being recreated if initialize() is retried (since _deviceOrientationSubscription remains non-null).

We should cancel the subscription and set it to null in the catch block to ensure proper cleanup and allow successful retries.

Suggested change
} on PlatformException catch (e) {
throw CameraException(e.code, e.message);
} on PlatformException catch (e) {
unawaited(_deviceOrientationSubscription?.cancel());
_deviceOrientationSubscription = null;
throw CameraException(e.code, e.message);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

/gemini

This is pre-existing behavior unrelated to the bug this PR fixes (a CameraController updating its value after being disposed).

The subscription is already cancelled in dispose(). It only lingers if the controller is never disposed, which is independent of whether initialization succeeds or fails. And since onDeviceOrientationChanged() is a global stream, reusing it on retry is intentional rather than a leak.

To keep this PR focused, I'd prefer to leave this out of scope, but I'm happy to address it in a separate PR if a maintainer thinks it's worth changing.

@motucraft motucraft force-pushed the fix/camera-controller-update-after-dispose branch 2 times, most recently from 61a4651 to b35d157 Compare June 11, 2026 01:27
@motucraft motucraft force-pushed the fix/camera-controller-update-after-dispose branch from b35d157 to 11c69d4 Compare June 20, 2026 06:03
Guards the `value` assignments in `_initializeWithDescription` so they no longer run after `dispose()`, fixing the "A CameraController was used after being disposed." crash.

Addresses the Dart-side crash in flutter/flutter#184959.
The native Android ANR discussed in that issue is a separate root cause and is not covered here.
@motucraft motucraft force-pushed the fix/camera-controller-update-after-dispose branch from 11c69d4 to 3f27e27 Compare July 2, 2026 02:34
@motucraft

Copy link
Copy Markdown
Contributor Author

@stuartmorgan-g
Could you let me know when this PR might be reviewed? It has been waiting for review for about three weeks.

@bparrishMines bparrishMines left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM

This seems like a reasonable fix. Thanks for the contribution!

@stuartmorgan-g / @tarrinneal for secondary review

@bparrishMines bparrishMines added the CICD Run CI/CD label Jul 8, 2026
@flutter-dashboard flutter-dashboard Bot removed the CICD Run CI/CD label Jul 13, 2026
@stuartmorgan-g stuartmorgan-g added autosubmit Merge PR when tree becomes green via auto submit App CICD Run CI/CD labels Jul 13, 2026
@auto-submit auto-submit Bot merged commit ad2eab1 into flutter:main Jul 13, 2026
89 checks passed
loic-sharma pushed a commit to ishaquehassan/flutter that referenced this pull request Jul 13, 2026
…er#189387)

flutter/packages@20928d5...ad2eab1

2026-07-13 35750184+motucraft@users.noreply.github.com [camera] Guard
CameraController value updates after dispose (flutter/packages#11861)
2026-07-13 dkwingsmt@users.noreply.github.com [material_ui] Remove
unused example files (flutter/packages#12179)
2026-07-13 puneetkukreja98@gmail.com
[google_maps_flutter_platform_interface] Adds support for
mapTypeControlEnabled, fullscreenControlEnabled, and
streetViewControlEnabled for web (flutter/packages#12191)
2026-07-13 44747303+theprantadutta@users.noreply.github.com [pigeon]
Report a clear error for enhanced enums (flutter/packages#11880)
2026-07-13 49699333+dependabot[bot]@users.noreply.github.com Bump
actions/labeler from 6.1.0 to 6.2.0 in the all-github-actions group
(flutter/packages#12190)
2026-07-13 stuartmorgan@google.com [shared_preferences] Convert legacy
codepath to Kotlin (flutter/packages#12139)
2026-07-12 engine-flutter-autoroll@skia.org Roll Flutter from
f7b66f3 to cf9e8af (11 revisions) (flutter/packages#12188)
2026-07-11 44525804+sailendrabathi@users.noreply.github.com
[video_player] Improve seek performance on Android
(flutter/packages#11810)
2026-07-11 stuartmorgan@google.com [pigeon] Disable iOS test
parallelization (flutter/packages#12177)
2026-07-11 dkwingsmt@users.noreply.github.com [material_ui,
cupertino_ui] Migrate snippet TODOs to `<callout-box>`
(flutter/packages#12146)
2026-07-11 dkwingsmt@users.noreply.github.com [cupertino_ui] Fix example
path (flutter/packages#12151)
2026-07-10 engine-flutter-autoroll@skia.org Roll Flutter from
dc2a870 to f7b66f3 (12 revisions) (flutter/packages#12175)
2026-07-10 engine-flutter-autoroll@skia.org Roll Flutter (stable) from
f94f4fc to ee80f08 (3 revisions) (flutter/packages#12171)
2026-07-10 engine-flutter-autoroll@skia.org Manual roll Flutter from
91939cc to dc2a870 (50 revisions) (flutter/packages#12169)
2026-07-09 jessiewong401@gmail.com Update `legacy` test to be in Warn
Range (flutter/packages#12168)
2026-07-09 dkwingsmt@users.noreply.github.com [material_ui,
cupertino_ui] Migrate dartpad TODOs to `<callout-box>`
(flutter/packages#12120)
2026-07-09 73310711+shrabanti722@users.noreply.github.com
[video_player_avfoundation] Implement
preventsDisplaySleepDuringVideoPlayback (flutter/packages#11547)
2026-07-09 44747303+theprantadutta@users.noreply.github.com [pigeon] Add
usage docs to generated Dart event channel methods
(flutter/packages#11894)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-packages-flutter-autoroll
Please CC flutter-ecosystem@google.com on the revert to ensure that a
human
is aware of the problem.

To file a bug in Flutter:
https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

autosubmit Merge PR when tree becomes green via auto submit App CICD Run CI/CD p: camera

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants