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

[camera_platform_interface] Migrate to null safety #3497

Merged
merged 15 commits into from
Feb 8, 2021
Merged
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_platform_interface/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 2.0.0-nullsafety

- Migrate to null safety.

## 1.6.0

- Added VideoRecordedEvent to support ending a video recording in the native implementation.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,12 @@ class CameraInitializedEvent extends CameraEvent {
CameraInitializedEvent(
int cameraId,
this.previewWidth,
this.previewHeight, [
this.previewHeight,
this.exposureMode,
this.exposurePointSupported = false,
this.exposurePointSupported,
this.focusMode,
this.focusPointSupported = false,
]) : super(cameraId);
this.focusPointSupported,
) : super(cameraId);

/// Converts the supplied [Map] to an instance of the [CameraInitializedEvent]
/// class.
Expand Down Expand Up @@ -242,7 +242,7 @@ class VideoRecordedEvent extends CameraEvent {
final XFile file;

/// Maximum duration of the recorded video.
final Duration maxVideoDuration;
final Duration? maxVideoDuration;

/// Build a VideoRecordedEvent triggered from the camera with the `cameraId`.
///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import 'package:camera_platform_interface/src/types/focus_mode.dart';
import 'package:camera_platform_interface/src/types/image_format_group.dart';
import 'package:camera_platform_interface/src/utils/utils.dart';
import 'package:cross_file/cross_file.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:meta/meta.dart';
Expand Down Expand Up @@ -58,8 +59,13 @@ class MethodChannelCamera extends CameraPlatform {
@override
Future<List<CameraDescription>> availableCameras() async {
try {
final List<Map<dynamic, dynamic>> cameras = await _channel
final cameras = await _channel
Comment on lines -61 to +62
Copy link
Member

Choose a reason for hiding this comment

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

I think we want left-hand types (but I'm not 100% sure), @bparrishMines?

Copy link
Contributor

Choose a reason for hiding this comment

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

It differs between plugins. If the general style within the plugin has left-hand types, then we should probably keep the pattern the same. We could also decide on a preference for the repo as a whole and add it to the global analysis_options.yaml. https://github.com/flutter/plugins/blob/master/analysis_options.yaml

.invokeListMethod<Map<dynamic, dynamic>>('availableCameras');

if (cameras == null) {
return <CameraDescription>[];
}

return cameras.map((Map<dynamic, dynamic> camera) {
return CameraDescription(
name: camera['name'],
Expand All @@ -75,30 +81,30 @@ class MethodChannelCamera extends CameraPlatform {
@override
Future<int> createCamera(
CameraDescription cameraDescription,
ResolutionPreset resolutionPreset, {
bool enableAudio,
ResolutionPreset? resolutionPreset, {
bool enableAudio = true,
}) async {
try {
final Map<String, dynamic> reply =
await _channel.invokeMapMethod<String, dynamic>(
'create',
<String, dynamic>{
'cameraName': cameraDescription.name,
'resolutionPreset': resolutionPreset != null
? _serializeResolutionPreset(resolutionPreset)
: null,
'enableAudio': enableAudio,
},
);
return reply['cameraId'];
final reply = await _channel
.invokeMapMethod<String, dynamic>('create', <String, dynamic>{
'cameraName': cameraDescription.name,
'resolutionPreset': resolutionPreset != null
? _serializeResolutionPreset(resolutionPreset)
: null,
'enableAudio': enableAudio,
});

return reply!['cameraId'];
} on PlatformException catch (e) {
throw CameraException(e.code, e.message);
}
}

@override
Future<void> initializeCamera(int cameraId,
{ImageFormatGroup imageFormatGroup}) {
Future<void> initializeCamera(
int cameraId, {
ImageFormatGroup imageFormatGroup = ImageFormatGroup.unknown,
}) {
_channels.putIfAbsent(cameraId, () {
final channel = MethodChannel('flutter.io/cameraPlugin/camera$cameraId');
channel.setMethodCallHandler(
Expand All @@ -125,15 +131,16 @@ class MethodChannelCamera extends CameraPlatform {

@override
Future<void> dispose(int cameraId) async {
if (_channels.containsKey(cameraId)) {
final cameraChannel = _channels[cameraId];
cameraChannel?.setMethodCallHandler(null);
_channels.remove(cameraId);
}

await _channel.invokeMethod<void>(
'dispose',
<String, dynamic>{'cameraId': cameraId},
);

if (_channels.containsKey(cameraId)) {
_channels[cameraId].setMethodCallHandler(null);
_channels.remove(cameraId);
}
}

@override
Expand Down Expand Up @@ -169,7 +176,9 @@ class MethodChannelCamera extends CameraPlatform {

@override
Future<void> lockCaptureOrientation(
int cameraId, DeviceOrientation orientation) async {
int cameraId,
DeviceOrientation orientation,
) async {
await _channel.invokeMethod<String>(
'lockCaptureOrientation',
<String, dynamic>{
Expand All @@ -189,10 +198,18 @@ class MethodChannelCamera extends CameraPlatform {

@override
Future<XFile> takePicture(int cameraId) async {
String path = await _channel.invokeMethod<String>(
final path = await _channel.invokeMethod<String>(
'takePicture',
<String, dynamic>{'cameraId': cameraId},
);

if (path == null) {
throw CameraException(
'INVALID_PATH',
'The platform "$defaultTargetPlatform" did not return a path while reporting success. The platform should always return a valid path or report an error.',
);
}

return XFile(path);
}

Expand All @@ -202,7 +219,7 @@ class MethodChannelCamera extends CameraPlatform {

@override
Future<void> startVideoRecording(int cameraId,
{Duration maxVideoDuration}) async {
{Duration? maxVideoDuration}) async {
await _channel.invokeMethod<void>(
'startVideoRecording',
<String, dynamic>{
Expand All @@ -214,10 +231,18 @@ class MethodChannelCamera extends CameraPlatform {

@override
Future<XFile> stopVideoRecording(int cameraId) async {
String path = await _channel.invokeMethod<String>(
final path = await _channel.invokeMethod<String>(
'stopVideoRecording',
<String, dynamic>{'cameraId': cameraId},
);

if (path == null) {
throw CameraException(
'INVALID_PATH',
'The platform "$defaultTargetPlatform" did not return a path while reporting success. The platform should always return a valid path or report an error.',
);
}

return XFile(path);
}

Expand Down Expand Up @@ -255,9 +280,10 @@ class MethodChannelCamera extends CameraPlatform {
);

@override
Future<void> setExposurePoint(int cameraId, Point<double> point) {
Future<void> setExposurePoint(int cameraId, Point<double>? point) {
assert(point == null || point.x >= 0 && point.x <= 1);
assert(point == null || point.y >= 0 && point.y <= 1);

return _channel.invokeMethod<void>(
'setExposurePoint',
<String, dynamic>{
Expand All @@ -270,35 +296,47 @@ class MethodChannelCamera extends CameraPlatform {
}

@override
Future<double> getMinExposureOffset(int cameraId) =>
_channel.invokeMethod<double>(
'getMinExposureOffset',
<String, dynamic>{'cameraId': cameraId},
);
Future<double> getMinExposureOffset(int cameraId) async {
final minExposureOffset = await _channel.invokeMethod<double>(
'getMinExposureOffset',
<String, dynamic>{'cameraId': cameraId},
);

return minExposureOffset!;
}

@override
Future<double> getMaxExposureOffset(int cameraId) =>
_channel.invokeMethod<double>(
'getMaxExposureOffset',
<String, dynamic>{'cameraId': cameraId},
);
Future<double> getMaxExposureOffset(int cameraId) async {
final maxExposureOffset = await _channel.invokeMethod<double>(
'getMaxExposureOffset',
<String, dynamic>{'cameraId': cameraId},
);

return maxExposureOffset!;
}

@override
Future<double> getExposureOffsetStepSize(int cameraId) =>
_channel.invokeMethod<double>(
'getExposureOffsetStepSize',
<String, dynamic>{'cameraId': cameraId},
);
Future<double> getExposureOffsetStepSize(int cameraId) async {
final stepSize = await _channel.invokeMethod<double>(
'getExposureOffsetStepSize',
<String, dynamic>{'cameraId': cameraId},
);

return stepSize!;
}

@override
Future<double> setExposureOffset(int cameraId, double offset) =>
_channel.invokeMethod<double>(
'setExposureOffset',
<String, dynamic>{
'cameraId': cameraId,
'offset': offset,
},
);
Future<double> setExposureOffset(int cameraId, double offset) async {
final appliedOffset = await _channel.invokeMethod<double>(
'setExposureOffset',
<String, dynamic>{
'cameraId': cameraId,
'offset': offset,
},
);

return appliedOffset!;
}

@override
Future<void> setFocusMode(int cameraId, FocusMode mode) =>
Expand All @@ -311,9 +349,10 @@ class MethodChannelCamera extends CameraPlatform {
);

@override
Future<void> setFocusPoint(int cameraId, Point<double> point) {
Future<void> setFocusPoint(int cameraId, Point<double>? point) {
assert(point == null || point.x >= 0 && point.x <= 1);
assert(point == null || point.y >= 0 && point.y <= 1);

return _channel.invokeMethod<void>(
'setFocusPoint',
<String, dynamic>{
Expand All @@ -326,16 +365,24 @@ class MethodChannelCamera extends CameraPlatform {
}

@override
Future<double> getMaxZoomLevel(int cameraId) => _channel.invokeMethod<double>(
'getMaxZoomLevel',
<String, dynamic>{'cameraId': cameraId},
);
Future<double> getMaxZoomLevel(int cameraId) async {
final maxZoomLevel = await _channel.invokeMethod<double>(
'getMaxZoomLevel',
<String, dynamic>{'cameraId': cameraId},
);

return maxZoomLevel!;
}

@override
Future<double> getMinZoomLevel(int cameraId) => _channel.invokeMethod<double>(
'getMinZoomLevel',
<String, dynamic>{'cameraId': cameraId},
);
Future<double> getMinZoomLevel(int cameraId) async {
final minZoomLevel = await _channel.invokeMethod<double>(
'getMinZoomLevel',
<String, dynamic>{'cameraId': cameraId},
);

return minZoomLevel!;
}

@override
Future<void> setZoomLevel(int cameraId, double zoom) async {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ abstract class CameraPlatform extends PlatformInterface {
/// Creates an uninitialized camera instance and returns the cameraId.
Future<int> createCamera(
CameraDescription cameraDescription,
ResolutionPreset resolutionPreset, {
bool enableAudio,
ResolutionPreset? resolutionPreset, {
bool enableAudio = true,
}) {
throw UnimplementedError('createCamera() is not implemented.');
}
Expand All @@ -62,8 +62,10 @@ abstract class CameraPlatform extends PlatformInterface {
/// [imageFormatGroup] is used to specify the image formatting used.
/// On Android this defaults to ImageFormat.YUV_420_888 and applies only to the imageStream.
/// On iOS this defaults to kCVPixelFormatType_32BGRA.
Future<void> initializeCamera(int cameraId,
{ImageFormatGroup imageFormatGroup}) {
Future<void> initializeCamera(
int cameraId, {
ImageFormatGroup imageFormatGroup = ImageFormatGroup.unknown,
}) {
throw UnimplementedError('initializeCamera() is not implemented.');
}

Expand Down Expand Up @@ -130,7 +132,7 @@ abstract class CameraPlatform extends PlatformInterface {
/// meaning the recording will continue until manually stopped.
/// With [maxVideoDuration] set the video is returned in a [VideoRecordedEvent]
/// through the [onVideoRecordedEvent] stream when the set duration is reached.
Future<void> startVideoRecording(int cameraId, {Duration maxVideoDuration}) {
Future<void> startVideoRecording(int cameraId, {Duration? maxVideoDuration}) {
throw UnimplementedError('startVideoRecording() is not implemented.');
}

Expand Down Expand Up @@ -160,7 +162,10 @@ abstract class CameraPlatform extends PlatformInterface {
}

/// Sets the exposure point for automatically determining the exposure values.
Future<void> setExposurePoint(int cameraId, Point<double> point) {
///
/// Supplying `null` for the [point] argument will result in resetting to the
/// original exposure point value.
Future<void> setExposurePoint(int cameraId, Point<double>? point) {
throw UnimplementedError('setExposurePoint() is not implemented.');
}

Expand Down Expand Up @@ -202,7 +207,10 @@ abstract class CameraPlatform extends PlatformInterface {
}

/// Sets the focus point for automatically determining the focus values.
Future<void> setFocusPoint(int cameraId, Point<double> point) {
///
/// Supplying `null` for the [point] argument will result in resetting to the
/// original focus point value.
Future<void> setFocusPoint(int cameraId, Point<double>? point) {
throw UnimplementedError('setFocusPoint() is not implemented.');
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ enum CameraLensDirection {
/// Properties of a camera device.
class CameraDescription {
/// Creates a new camera description with the given properties.
CameraDescription({this.name, this.lensDirection, this.sensorOrientation});
CameraDescription({
required this.name,
required this.lensDirection,
required this.sensorOrientation,
});

/// The name of the camera device.
final String name;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class CameraException implements Exception {
String code;

/// Textual description of the error.
String description;
String? description;

@override
String toString() => 'CameraException($code, $description)';
Expand Down
Loading