Repository navigation
[camera] CameraController.setDescription and dispose don't work as expected #126823
Copy link
Copy link
Closed
Labels
P2Important issues not at the top of the work listImportant issues not at the top of the work listfound in release: 3.10Found to occur in 3.10Found to occur in 3.10found in release: 3.11Found to occur in 3.11Found to occur in 3.11has reproducible stepsThe issue has been confirmed reproducible and is ready to work onThe issue has been confirmed reproducible and is ready to work onp: cameraThe camera pluginThe camera pluginpackageflutter/packages repository. See also p: labels.flutter/packages repository. See also p: labels.r: fixedIssue is closed as already fixed in a newer versionIssue is closed as already fixed in a newer versionteam-ecosystemOwned by Ecosystem teamOwned by Ecosystem teamtriaged-ecosystemTriaged by Ecosystem teamTriaged by Ecosystem team
Description
Is there an existing issue for this?
- I have searched the existing issues
- I have read the guide to filing a bug
Steps to reproduce
- Initialize a CameraController
- Set a different CameraDescription via setDescription
- Dispose of the controller
- Initialize a new CameraController
- Observer a ChangeNotifier exception
Expected results
No ChangeNotifier exceptions.
Actual results
E/flutter (12815): Once you have called dispose() on a CameraController, it can no longer be used.
E/flutter (12815): #0 ChangeNotifier.debugAssertNotDisposed.<anonymous closure>
change_notifier.dart:179
E/flutter (12815): #1 ChangeNotifier.debugAssertNotDisposed
change_notifier.dart:186
E/flutter (12815): #2 ChangeNotifier.notifyListeners
change_notifier.dart:382
E/flutter (12815): #3 ValueNotifier.value=
change_notifier.dart:530
E/flutter (12815): #4 CameraController._initializeWithDescription.<anonymous closure>
camera_controller.dart:304
E/flutter (12815): #5 _RootZone.runUnaryGuarded (dart:async/zone.dart:1594:10)
E/flutter (12815): #6 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:339:11)
E/flutter (12815): #7 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
E/flutter (12815): #8 _SyncBroadcastStreamController._sendData (dart:async/broadcast_stream_controller.dart:377:25)
E/flutter (12815): #9 _BroadcastStreamController.add (dart:async/broadcast_stream_controller.dart:244:5)
E/flutter (12815): #10 Where.whereType.<anonymous closure>
where.dart:21
E/flutter (12815): #11 TransformByHandlers.transformByHandlers.<anonymous closure>.<anonymous closure>
from_handlers.dart:29
E/flutter (12815): #12 _RootZone.runUnaryGuarded (dart:async/zone.dart:1594:10)
E/flutter (12815): #13 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:339:11)
E/flutter (12815): #14 _DelayedData.perform (dart:async/stream_impl.dart:515:14)
E/flutter (12815): #15 _PendingEvents.handleNext (dart:async/stream_impl.dart:620:11)
E/flutter (12815): #16 _PendingEvents.schedule.<anonymous closure> (dart:async/stream_impl.dart:591:7)
E/flutter (12815): #17 _microtaskLoop (dart:async/schedule_microtask.dart:40:21)
E/flutter (12815): #18 _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5)
Code sample
Not providing a code sample since, I think I know where the issue is:
If we look at:
CameraController.setDescription we see the new description is set up by calling _initializeWithDescription.
If we look at _initializeWithDescription, we see _deviceOrientationSubscription is set up through direct assignment and subscription to the CameraPlatform.instance.onDeviceOrientationChanged() stream.
Code:
_deviceOrientationSubscription = CameraPlatform.instance
.onDeviceOrientationChanged()
.listen((DeviceOrientationChangedEvent event) {
value = value.copyWith(
deviceOrientation: event.orientation,
);
});The _deviceOrientationSubscription is never cancelled in case we set up a new description, it is simply reassigned.
My guess would be to simply assign the _deviceOrientationSubscription using ??=.
Screenshots or Video
No response
Logs
No response
Flutter Doctor output
Doctor output
[✓] Flutter (Channel stable, 3.10.0, on macOS 11.7.6 20G1231 darwin-x64, locale en-GB)
• Flutter version 3.10.0 on channel stable at /usr/local/flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 84a1e904f4 (6 days ago), 2023-05-09 07:41:44 -0700
• Engine revision d44b5a94c9
• Dart version 3.0.0
• DevTools version 2.23.1
[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
• Android SDK at /Users/jellynoone/Library/Android/sdk
• Platform android-33, build-tools 33.0.0
• Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)
• All Android licenses accepted.
[!] Xcode - develop for iOS and macOS (Xcode 13.2.1)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Build 13C100
✗ CocoaPods not installed.
CocoaPods is used to retrieve the iOS and macOS platform side's plugin code that responds to your plugin usage on the Dart side.
Without CocoaPods, plugins will not work on iOS or macOS.
For more info, see https://flutter.dev/platform-plugins
To install see https://guides.cocoapods.org/using/getting-started.html#installation for instructions.
[✓] Chrome - develop for the web
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[✓] Android Studio (version 2022.2)
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)
[✓] VS Code (version 1.79.0-insider)
• VS Code at /Applications/Visual Studio Code - Insiders.app/Contents
• Flutter extension version 3.64.0
[✓] Connected device (3 available)
• Pixel (mobile) • FA76R0301797 • android-arm64 • Android 10 (API 29)
• macOS (desktop) • macos • darwin-x64 • macOS 11.7.6 20G1231 darwin-x64
• Chrome (web) • chrome • web-javascript • Google Chrome 113.0.5672.92
[✓] Network resources
• All expected network resources are available.
! Doctor found issues in 1 category.Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
P2Important issues not at the top of the work listImportant issues not at the top of the work listfound in release: 3.10Found to occur in 3.10Found to occur in 3.10found in release: 3.11Found to occur in 3.11Found to occur in 3.11has reproducible stepsThe issue has been confirmed reproducible and is ready to work onThe issue has been confirmed reproducible and is ready to work onp: cameraThe camera pluginThe camera pluginpackageflutter/packages repository. See also p: labels.flutter/packages repository. See also p: labels.r: fixedIssue is closed as already fixed in a newer versionIssue is closed as already fixed in a newer versionteam-ecosystemOwned by Ecosystem teamOwned by Ecosystem teamtriaged-ecosystemTriaged by Ecosystem teamTriaged by Ecosystem team
Activity
jellynoone commentedon May 15, 2023
Further analysis:
So the error I'm getting is really an error that happens due to the subscription not being cancelled after a new CameraDescription is set while the controller is active.
We dispose the new subscription that is made up in the second initialization call but the first one gets lost in the process.
When we then dispose the controller, the subscription is still active.
I think its fine to simply write:
jellynoone commentedon May 15, 2023
Additionally, I'm not entirely sure simply initialising the new camera is enough here. Shouldn't we first dispose the old camera id? Using,
CameraPlatform.instance.dispose.cc: @BradenBagby, @stuartmorgan
BradenBagby commentedon May 15, 2023
Thanks for catching this! Are you able to provide a code sample? The camera example app appears to work with no errors
BradenBagby commentedon May 15, 2023
I have modified the example camera code to dispose and re-initialize the camera controller every time and am still not seeing any errors
jellynoone commentedon May 15, 2023
Example below:
If you have uncaught exceptions enabled, you should see the exception in the editor, otherwise in the logs.
BradenBagby commentedon May 15, 2023
Thank you I am seeing the error!
darshankawar commentedon May 16, 2023
Thanks for the detailed report. I was able to replicate the reported behavior.
stable, master flutter doctor -v
ibrahimdevs commentedon May 30, 2023
After hours of struggle, finally I can able to think that it may not my fault :)
I can confirm this issue. This is totally related with "setDescription" function.
As a not optimum workaround, you can dispose the cameraController and init again.
Sh1d0w commentedon Jun 3, 2023
@ibrahimdevs thanks for the solution, works for now.
I was going insane debugging the issue for hours, I thought it was issue in my code. Hope it gets fixed soon.
[camera] Dispose resources correctly on setDescription (#4003)
namanshergill commentedon Jan 16, 2024
Shouldn’t this issue be closed now that the fix is released?
stuartmorgan-g commentedon Jan 16, 2024
Thanks for noticing; the PR just didn't have quite the right phrasing to have GitHub auto-close the issue.
github-actions commentedon Jan 31, 2024
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of
flutter doctor -vand a minimal reproduction of the issue.