Skip to content

Commit dac4b6f

Browse files
[camera_platform_interface] Add platform interface methods for setting auto focus. (#3369)
* Added platform interface methods for setting auto exposure. * Added platform interface methods for setting auto exposure. * Remove workspace files * Added auto exposure implementations for Android and iOS * Added platform interface methods for managing auto focus. * Formatted code * Export focus mode * Update platform interface for changes to autofocus methods * Revert "Update platform interface for changes to autofocus methods" This reverts commit bdeed1d213a9f106d0bd80b8905c0ae3af29886e. * iOS fix for setting the exposure point * Removed unnecessary check * Updated changelog and pubspec.yaml * Update platform interface dependency * Implement PR feedback * Restore test * Revert test change * Update camera pubspec * Update platform interface to prevent breaking changes with current master Co-authored-by: Maurits van Beusekom <[email protected]>
1 parent b64bebf commit dac4b6f

File tree

12 files changed

+291
-42
lines changed

12 files changed

+291
-42
lines changed

packages/camera/camera_platform_interface/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 1.4.0
2+
3+
- Added interface methods to support auto focus.
4+
15
## 1.3.0
26

37
- Introduces an option to set the image format when initializing.

packages/camera/camera_platform_interface/lib/src/events/camera_event.dart

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5+
import 'package:camera_platform_interface/src/types/focus_mode.dart';
6+
57
import '../../camera_platform_interface.dart';
68

79
/// Generic Event coming from the native side of Camera.
@@ -50,9 +52,15 @@ class CameraInitializedEvent extends CameraEvent {
5052
/// The default exposure mode
5153
final ExposureMode exposureMode;
5254

55+
/// The default focus mode
56+
final FocusMode focusMode;
57+
5358
/// Whether setting exposure points is supported.
5459
final bool exposurePointSupported;
5560

61+
/// Whether setting focus points is supported.
62+
final bool focusPointSupported;
63+
5664
/// Build a CameraInitialized event triggered from the camera represented by
5765
/// `cameraId`.
5866
///
@@ -61,18 +69,22 @@ class CameraInitializedEvent extends CameraEvent {
6169
CameraInitializedEvent(
6270
int cameraId,
6371
this.previewWidth,
64-
this.previewHeight,
72+
this.previewHeight, [
6573
this.exposureMode,
66-
this.exposurePointSupported,
67-
) : super(cameraId);
74+
this.exposurePointSupported = false,
75+
this.focusMode,
76+
this.focusPointSupported = false,
77+
]) : super(cameraId);
6878

6979
/// Converts the supplied [Map] to an instance of the [CameraInitializedEvent]
7080
/// class.
7181
CameraInitializedEvent.fromJson(Map<String, dynamic> json)
7282
: previewWidth = json['previewWidth'],
7383
previewHeight = json['previewHeight'],
7484
exposureMode = deserializeExposureMode(json['exposureMode']),
75-
exposurePointSupported = json['exposurePointSupported'],
85+
exposurePointSupported = json['exposurePointSupported'] ?? false,
86+
focusMode = deserializeFocusMode(json['focusMode']),
87+
focusPointSupported = json['focusPointSupported'] ?? false,
7688
super(json['cameraId']);
7789

7890
/// Converts the [CameraInitializedEvent] instance into a [Map] instance that
@@ -83,6 +95,8 @@ class CameraInitializedEvent extends CameraEvent {
8395
'previewHeight': previewHeight,
8496
'exposureMode': serializeExposureMode(exposureMode),
8597
'exposurePointSupported': exposurePointSupported,
98+
'focusMode': serializeFocusMode(focusMode),
99+
'focusPointSupported': focusPointSupported,
86100
};
87101

88102
@override
@@ -94,15 +108,19 @@ class CameraInitializedEvent extends CameraEvent {
94108
previewWidth == other.previewWidth &&
95109
previewHeight == other.previewHeight &&
96110
exposureMode == other.exposureMode &&
97-
exposurePointSupported == other.exposurePointSupported;
111+
exposurePointSupported == other.exposurePointSupported &&
112+
focusMode == other.focusMode &&
113+
focusPointSupported == other.focusPointSupported;
98114

99115
@override
100116
int get hashCode =>
101117
super.hashCode ^
102118
previewWidth.hashCode ^
103119
previewHeight.hashCode ^
104120
exposureMode.hashCode ^
105-
exposurePointSupported.hashCode;
121+
exposurePointSupported.hashCode ^
122+
focusMode.hashCode ^
123+
focusPointSupported.hashCode;
106124
}
107125

108126
/// An event fired when the resolution preset of the camera has changed.

packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'dart:async';
66
import 'dart:math';
77

88
import 'package:camera_platform_interface/camera_platform_interface.dart';
9+
import 'package:camera_platform_interface/src/types/focus_mode.dart';
910
import 'package:camera_platform_interface/src/types/image_format_group.dart';
1011
import 'package:camera_platform_interface/src/utils/utils.dart';
1112
import 'package:cross_file/cross_file.dart';
@@ -249,6 +250,31 @@ class MethodChannelCamera extends CameraPlatform {
249250
},
250251
);
251252

253+
@override
254+
Future<void> setFocusMode(int cameraId, FocusMode mode) =>
255+
_channel.invokeMethod<void>(
256+
'setFocusMode',
257+
<String, dynamic>{
258+
'cameraId': cameraId,
259+
'mode': serializeFocusMode(mode),
260+
},
261+
);
262+
263+
@override
264+
Future<void> setFocusPoint(int cameraId, Point<double> point) {
265+
assert(point == null || point.x >= 0 && point.x <= 1);
266+
assert(point == null || point.y >= 0 && point.y <= 1);
267+
return _channel.invokeMethod<void>(
268+
'setFocusPoint',
269+
<String, dynamic>{
270+
'cameraId': cameraId,
271+
'reset': point == null,
272+
'x': point?.x,
273+
'y': point?.y,
274+
},
275+
);
276+
}
277+
252278
@override
253279
Future<double> getMaxZoomLevel(int cameraId) => _channel.invokeMethod<double>(
254280
'getMaxZoomLevel',
@@ -331,6 +357,8 @@ class MethodChannelCamera extends CameraPlatform {
331357
call.arguments['previewHeight'],
332358
deserializeExposureMode(call.arguments['exposureMode']),
333359
call.arguments['exposurePointSupported'],
360+
deserializeFocusMode(call.arguments['focusMode']),
361+
call.arguments['focusPointSupported'],
334362
));
335363
break;
336364
case 'resolution_changed':

packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import 'dart:math';
88
import 'package:camera_platform_interface/camera_platform_interface.dart';
99
import 'package:camera_platform_interface/src/method_channel/method_channel_camera.dart';
1010
import 'package:camera_platform_interface/src/types/exposure_mode.dart';
11+
import 'package:camera_platform_interface/src/types/focus_mode.dart';
1112
import 'package:camera_platform_interface/src/types/image_format_group.dart';
1213
import 'package:cross_file/cross_file.dart';
1314
import 'package:flutter/widgets.dart';
@@ -129,7 +130,7 @@ abstract class CameraPlatform extends PlatformInterface {
129130
throw UnimplementedError('setExposureMode() is not implemented.');
130131
}
131132

132-
/// Sets the exposure point for automatically determining the exposure value.
133+
/// Sets the exposure point for automatically determining the exposure values.
133134
Future<void> setExposurePoint(int cameraId, Point<double> point) {
134135
throw UnimplementedError('setExposurePoint() is not implemented.');
135136
}
@@ -166,6 +167,16 @@ abstract class CameraPlatform extends PlatformInterface {
166167
throw UnimplementedError('setExposureOffset() is not implemented.');
167168
}
168169

170+
/// Sets the focus mode for taking pictures.
171+
Future<void> setFocusMode(int cameraId, FocusMode mode) {
172+
throw UnimplementedError('setFocusMode() is not implemented.');
173+
}
174+
175+
/// Sets the focus point for automatically determining the focus values.
176+
Future<void> setFocusPoint(int cameraId, Point<double> point) {
177+
throw UnimplementedError('setFocusPoint() is not implemented.');
178+
}
179+
169180
/// Gets the maximum supported zoom level for the selected camera.
170181
Future<double> getMaxZoomLevel(int cameraId) {
171182
throw UnimplementedError('getMaxZoomLevel() is not implemented.');

packages/camera/camera_platform_interface/lib/src/types/exposure_mode.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ enum ExposureMode {
1313

1414
/// Returns the exposure mode as a String.
1515
String serializeExposureMode(ExposureMode exposureMode) {
16+
if (exposureMode == null) return null;
1617
switch (exposureMode) {
1718
case ExposureMode.locked:
1819
return 'locked';
@@ -25,6 +26,7 @@ String serializeExposureMode(ExposureMode exposureMode) {
2526

2627
/// Returns the exposure mode for a given String.
2728
ExposureMode deserializeExposureMode(String str) {
29+
if (str == null) return null;
2830
switch (str) {
2931
case "locked":
3032
return ExposureMode.locked;
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright 2019 The Chromium Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
/// The possible focus modes that can be set for a camera.
6+
enum FocusMode {
7+
/// Automatically determine focus settings.
8+
auto,
9+
10+
/// Lock the currently determined focus settings.
11+
locked,
12+
}
13+
14+
/// Returns the focus mode as a String.
15+
String serializeFocusMode(FocusMode focusMode) {
16+
if (focusMode == null) return null;
17+
switch (focusMode) {
18+
case FocusMode.locked:
19+
return 'locked';
20+
case FocusMode.auto:
21+
return 'auto';
22+
default:
23+
throw ArgumentError('Unknown FocusMode value');
24+
}
25+
}
26+
27+
/// Returns the focus mode for a given String.
28+
FocusMode deserializeFocusMode(String str) {
29+
if (str == null) return null;
30+
switch (str) {
31+
case "locked":
32+
return FocusMode.locked;
33+
case "auto":
34+
return FocusMode.auto;
35+
default:
36+
throw ArgumentError('"$str" is not a valid FocusMode value');
37+
}
38+
}

packages/camera/camera_platform_interface/lib/src/types/types.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ export 'camera_exception.dart';
88
export 'flash_mode.dart';
99
export 'image_format_group.dart';
1010
export 'exposure_mode.dart';
11+
export 'focus_mode.dart';

packages/camera/camera_platform_interface/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ description: A common platform interface for the camera plugin.
33
homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera_platform_interface
44
# NOTE: We strongly prefer non-breaking changes, even at the expense of a
55
# less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes
6-
version: 1.3.0
6+
version: 1.4.0
77

88
dependencies:
99
flutter:

packages/camera/camera_platform_interface/test/camera_platform_interface_test.dart

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,32 @@ void main() {
264264
);
265265
});
266266

267+
test(
268+
'Default implementation of setFocusMode() should throw unimplemented error',
269+
() {
270+
// Arrange
271+
final cameraPlatform = ExtendsCameraPlatform();
272+
273+
// Act & Assert
274+
expect(
275+
() => cameraPlatform.setFocusMode(1, null),
276+
throwsUnimplementedError,
277+
);
278+
});
279+
280+
test(
281+
'Default implementation of setFocusPoint() should throw unimplemented error',
282+
() {
283+
// Arrange
284+
final cameraPlatform = ExtendsCameraPlatform();
285+
286+
// Act & Assert
287+
expect(
288+
() => cameraPlatform.setFocusPoint(1, null),
289+
throwsUnimplementedError,
290+
);
291+
});
292+
267293
test(
268294
'Default implementation of startVideoRecording() should throw unimplemented error',
269295
() {

0 commit comments

Comments
 (0)