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