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

[camera] Improve the camera example with controllers initializations #5748

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/camera/camera/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.9.6+1

* Improve the example to update the controller only if it's initialized successfully.

## 0.9.6

* Adds audio access permission handling logic on iOS to fix an issue with `prepareForVideoRecording` not awaiting for the audio permission request result.
Expand Down
30 changes: 18 additions & 12 deletions packages/camera/camera/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -651,39 +651,45 @@ class _CameraExampleHomeState extends State<CameraExampleHome>
imageFormatGroup: ImageFormatGroup.jpeg,
);

controller = cameraController;
Copy link
Contributor

Choose a reason for hiding this comment

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

With this change, wouldn't two calls to onNewCameraSelected in rapid succession have a race where a controller would be replaced without being disposed?

Copy link
Member Author

Choose a reason for hiding this comment

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

I think it is not covered in this PR yet. Let me know if the example can be updated/refactored for better architecture or for test purposes.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sure, anything we can do to make the example better is a win. We should try to make sure that testability changes are minimally intrusive when possible so they don't distract from understanding of the example itself.


// If the controller is updated then update the UI.
cameraController.addListener(() {
if (mounted) {
setState(() {});
}
if (cameraController.value.hasError) {
showInSnackBar(
'Camera error ${cameraController.value.errorDescription}');
'Camera error ${cameraController.value.errorDescription}',
);
}
});

try {
await cameraController.initialize();
await Future.wait(<Future<Object?>>[
// The exposure mode is currently not supported on the web.
...!kIsWeb
? <Future<Object?>>[
cameraController.getMinExposureOffset().then(
(double value) => _minAvailableExposureOffset = value),
cameraController
.getMaxExposureOffset()
.then((double value) => _maxAvailableExposureOffset = value)
]
: <Future<Object?>>[],
if (!kIsWeb) ...<Future<Object?>>[
cameraController
.getMinExposureOffset()
.then((double value) => _minAvailableExposureOffset = value),
cameraController
.getMaxExposureOffset()
.then((double value) => _maxAvailableExposureOffset = value),
],
Copy link
Contributor

Choose a reason for hiding this comment

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

is this just re-formatting?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yep.

cameraController
.getMaxZoomLevel()
.then((double value) => _maxAvailableZoom = value),
cameraController
.getMinZoomLevel()
.then((double value) => _minAvailableZoom = value),
]);
// `controller` needs to be set until it's fully initialized to avoid a
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this supposed to say "needs to be unset"?

// race condition when the lifecycle callback is being called and creates
// a new `controller`. This happens when the camera permission dialog
// dismisses at the first run, which triggers `didChangeAppLifecycleState`
// that disposes and re-creates the controller. Switching controllers in a
// short circumstance might cause the camera preview flashes or make the
// state hard to manage.
controller = cameraController;
} on CameraException catch (e) {
switch (e.code) {
case 'CameraAccessDenied':
Expand Down
2 changes: 1 addition & 1 deletion packages/camera/camera/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: A Flutter plugin for controlling the camera. Supports previewing
Dart.
repository: https://github.com/flutter/plugins/tree/main/packages/camera/camera
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22
version: 0.9.6
version: 0.9.6+1

environment:
sdk: ">=2.14.0 <3.0.0"
Expand Down