Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Improved error handling a bit & updated tests.
  • Loading branch information
BeMacized committed Jan 12, 2021
commit f478a5d48af2fbe46a756823665f682d24f0855a
8 changes: 6 additions & 2 deletions packages/camera/camera/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -572,8 +572,12 @@ class _CameraExampleHomeState extends State<CameraExampleHome>
try {
await controller.initialize();
await Future.wait([
controller.getMinExposureOffset().then((value) => _minAvailableExposureOffset = value),
controller.getMaxExposureOffset().then((value) => _maxAvailableExposureOffset = value),
controller
.getMinExposureOffset()
.then((value) => _minAvailableExposureOffset = value),
controller
.getMaxExposureOffset()
.then((value) => _maxAvailableExposureOffset = value),
controller.getMaxZoomLevel().then((value) => _maxAvailableZoom = value),
controller.getMinZoomLevel().then((value) => _minAvailableZoom = value),
]);
Expand Down
129 changes: 30 additions & 99 deletions packages/camera/camera/lib/src/camera_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -285,12 +285,7 @@ class CameraController extends ValueNotifier<CameraValue> {
///
/// Throws a [CameraException] if the capture fails.
Future<XFile> takePicture() async {
if (!value.isInitialized || _isDisposed) {
throw CameraException(
'Uninitialized CameraController.',
'takePicture was called on uninitialized CameraController',
);
}
_throwIfNotInitialized("takePicture");
if (value.isTakingPicture) {
throw CameraException(
'Previous capture has not returned yet.',
Expand Down Expand Up @@ -328,13 +323,7 @@ class CameraController extends ValueNotifier<CameraValue> {
Future<void> startImageStream(onLatestImageAvailable onAvailable) async {
assert(defaultTargetPlatform == TargetPlatform.android ||
defaultTargetPlatform == TargetPlatform.iOS);

if (!value.isInitialized || _isDisposed) {
throw CameraException(
'Uninitialized CameraController',
'startImageStream was called on uninitialized CameraController.',
);
}
_throwIfNotInitialized("startImageStream");
if (value.isRecordingVideo) {
throw CameraException(
'A video recording is already started.',
Expand Down Expand Up @@ -374,13 +363,7 @@ class CameraController extends ValueNotifier<CameraValue> {
Future<void> stopImageStream() async {
assert(defaultTargetPlatform == TargetPlatform.android ||
defaultTargetPlatform == TargetPlatform.iOS);

if (!value.isInitialized || _isDisposed) {
throw CameraException(
'Uninitialized CameraController',
'stopImageStream was called on uninitialized CameraController.',
);
}
_throwIfNotInitialized("stopImageStream");
if (value.isRecordingVideo) {
throw CameraException(
'A video recording is already started.',
Expand Down Expand Up @@ -410,12 +393,7 @@ class CameraController extends ValueNotifier<CameraValue> {
/// The video is returned as a [XFile] after calling [stopVideoRecording].
/// Throws a [CameraException] if the capture fails.
Future<void> startVideoRecording() async {
if (!value.isInitialized || _isDisposed) {
throw CameraException(
'Uninitialized CameraController',
'startVideoRecording was called on uninitialized CameraController',
);
}
_throwIfNotInitialized("startVideoRecording");
if (value.isRecordingVideo) {
throw CameraException(
'A video recording is already started.',
Expand All @@ -441,12 +419,7 @@ class CameraController extends ValueNotifier<CameraValue> {
///
/// Throws a [CameraException] if the capture failed.
Future<XFile> stopVideoRecording() async {
if (!value.isInitialized || _isDisposed) {
throw CameraException(
'Uninitialized CameraController',
'stopVideoRecording was called on uninitialized CameraController',
);
}
_throwIfNotInitialized("stopVideoRecording");
if (!value.isRecordingVideo) {
throw CameraException(
'No video is recording',
Expand All @@ -466,12 +439,7 @@ class CameraController extends ValueNotifier<CameraValue> {
///
/// This feature is only available on iOS and Android sdk 24+.
Future<void> pauseVideoRecording() async {
if (!value.isInitialized || _isDisposed) {
throw CameraException(
'Uninitialized CameraController',
'pauseVideoRecording was called on uninitialized CameraController',
);
}
_throwIfNotInitialized("pauseVideoRecording");
if (!value.isRecordingVideo) {
throw CameraException(
'No video is recording',
Expand All @@ -490,12 +458,7 @@ class CameraController extends ValueNotifier<CameraValue> {
///
/// This feature is only available on iOS and Android sdk 24+.
Future<void> resumeVideoRecording() async {
if (!value.isInitialized || _isDisposed) {
throw CameraException(
'Uninitialized CameraController',
'resumeVideoRecording was called on uninitialized CameraController',
);
}
_throwIfNotInitialized("resumeVideoRecording");
if (!value.isRecordingVideo) {
throw CameraException(
'No video is recording',
Expand All @@ -512,12 +475,7 @@ class CameraController extends ValueNotifier<CameraValue> {

/// Returns a widget showing a live camera preview.
Widget buildPreview() {
if (!value.isInitialized || _isDisposed) {
throw CameraException(
'Uninitialized CameraController',
'buildView() was called on uninitialized CameraController.',
);
}
_throwIfNotInitialized("buildPreview");
try {
return CameraPlatform.instance.buildPreview(_cameraId);
} on PlatformException catch (e) {
Expand All @@ -527,13 +485,7 @@ class CameraController extends ValueNotifier<CameraValue> {

/// Gets the maximum supported zoom level for the selected camera.
Future<double> getMaxZoomLevel() {
if (!value.isInitialized || _isDisposed) {
throw CameraException(
'Uninitialized CameraController',
'getMaxZoomLevel was called on uninitialized CameraController',
);
}

_throwIfNotInitialized("getMaxZoomLevel");
try {
return CameraPlatform.instance.getMaxZoomLevel(_cameraId);
} on PlatformException catch (e) {
Expand All @@ -543,13 +495,7 @@ class CameraController extends ValueNotifier<CameraValue> {

/// Gets the minimum supported zoom level for the selected camera.
Future<double> getMinZoomLevel() {
if (!value.isInitialized || _isDisposed) {
throw CameraException(
'Uninitialized CameraController',
'getMinZoomLevel was called on uninitialized CameraController',
);
}

_throwIfNotInitialized("getMinZoomLevel");
try {
return CameraPlatform.instance.getMinZoomLevel(_cameraId);
} on PlatformException catch (e) {
Expand All @@ -563,13 +509,7 @@ class CameraController extends ValueNotifier<CameraValue> {
/// zoom level returned by the `getMaxZoomLevel`. Throws an `CameraException`
/// when an illegal zoom level is suplied.
Future<void> setZoomLevel(double zoom) {
if (!value.isInitialized || _isDisposed) {
throw CameraException(
'Uninitialized CameraController',
'setZoomLevel was called on uninitialized CameraController',
);
}

_throwIfNotInitialized("setZoomLevel");
try {
return CameraPlatform.instance.setZoomLevel(_cameraId, zoom);
} on PlatformException catch (e) {
Expand Down Expand Up @@ -621,13 +561,7 @@ class CameraController extends ValueNotifier<CameraValue> {

/// Gets the minimum supported exposure offset for the selected camera in EV units.
Future<double> getMinExposureOffset() async {
if (!value.isInitialized || _isDisposed) {
throw CameraException(
'Uninitialized CameraController',
'getMinExposureOffset was called on uninitialized CameraController',
);
}

_throwIfNotInitialized("getMinExposureOffset");
try {
return CameraPlatform.instance.getMinExposureOffset(_cameraId);
} on PlatformException catch (e) {
Expand All @@ -637,13 +571,7 @@ class CameraController extends ValueNotifier<CameraValue> {

/// Gets the maximum supported exposure offset for the selected camera in EV units.
Future<double> getMaxExposureOffset() async {
if (!value.isInitialized || _isDisposed) {
throw CameraException(
'Uninitialized CameraController',
'getMaxExposureOffset was called on uninitialized CameraController',
);
}

_throwIfNotInitialized("getMaxExposureOffset");
try {
return CameraPlatform.instance.getMaxExposureOffset(_cameraId);
} on PlatformException catch (e) {
Expand All @@ -655,13 +583,7 @@ class CameraController extends ValueNotifier<CameraValue> {
///
/// Returns 0 when the camera supports using a free value without stepping.
Future<double> getExposureOffsetStepSize() async {
if (!value.isInitialized || _isDisposed) {
throw CameraException(
'Uninitialized CameraController',
'getExposureOffsetStepSize was called on uninitialized CameraController',
);
}

_throwIfNotInitialized("getExposureOffsetStepSize");
try {
return CameraPlatform.instance.getExposureOffsetStepSize(_cameraId);
} on PlatformException catch (e) {
Expand All @@ -681,13 +603,7 @@ class CameraController extends ValueNotifier<CameraValue> {
///
/// Returns the (rounded) offset value that was set.
Future<double> setExposureOffset(double offset) async {
if (!value.isInitialized || _isDisposed) {
throw CameraException(
'Uninitialized CameraController',
'setExposureOffset was called on uninitialized CameraController',
);
}

_throwIfNotInitialized("setExposureOffset");
// Check if offset is in range
List<double> range =
await Future.wait([getMinExposureOffset(), getMaxExposureOffset()]);
Expand Down Expand Up @@ -763,4 +679,19 @@ class CameraController extends ValueNotifier<CameraValue> {
await CameraPlatform.instance.dispose(_cameraId);
}
}

void _throwIfNotInitialized(String functionName) {
if (!value.isInitialized) {
throw CameraException(
'Uninitialized CameraController',
'$functionName() was called on an uninitialized CameraController.',
);
}
if (_isDisposed) {
throw CameraException(
'Disposed CameraController',
'$functionName() was called on a disposed CameraController.',
);
}
}
}
42 changes: 30 additions & 12 deletions packages/camera/camera/test/camera_image_stream_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,21 @@ void main() {
ResolutionPreset.max);

expect(
() => cameraController.startImageStream((image) => null),
throwsA(isA<CameraException>().having(
(error) => error.description,
'Uninitialized CameraController.',
'startImageStream was called on uninitialized CameraController.',
)));
() => cameraController.startImageStream((image) => null),
throwsA(
isA<CameraException>()
.having(
(error) => error.code,
'code',
'Uninitialized CameraController',
)
.having(
(error) => error.description,
'description',
'startImageStream() was called on an uninitialized CameraController.',
),
),
);
});

test('startImageStream() throws $CameraException when recording videos',
Expand Down Expand Up @@ -107,12 +116,21 @@ void main() {
ResolutionPreset.max);

expect(
cameraController.stopImageStream,
throwsA(isA<CameraException>().having(
(error) => error.description,
'Uninitialized CameraController.',
'stopImageStream was called on uninitialized CameraController.',
)));
cameraController.stopImageStream,
throwsA(
isA<CameraException>()
.having(
(error) => error.code,
'code',
'Uninitialized CameraController',
)
.having(
(error) => error.description,
'description',
'stopImageStream() was called on an uninitialized CameraController.',
),
),
);
});

test('stopImageStream() throws $CameraException when recording videos',
Expand Down
Loading