Skip to content

Commit 2c8f226

Browse files
[camera] Use Pigeon for Windows C++->Dart (#8001)
Replaces direct method channel usage with Pigeon for C++-to-Dart communication. On the Dart side, this re-uses the same structure used in other platform implementations. Part of http://github.com/flutter/flutter/issues/117905
1 parent 195b2d6 commit 2c8f226

File tree

11 files changed

+543
-344
lines changed

11 files changed

+543
-344
lines changed

packages/camera/camera_windows/CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
## NEXT
1+
## 0.2.5+1
22

3+
* Updates C++ to Dart communication to use Pigeon.
34
* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3.
45

56
## 0.2.5

packages/camera/camera_windows/lib/camera_windows.dart

Lines changed: 40 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,11 @@ class CameraWindows extends CameraPlatform {
2727
/// Interface for calling host-side code.
2828
final CameraApi _hostApi;
2929

30-
/// Camera specific method channels to allow communicating with specific cameras.
31-
final Map<int, MethodChannel> _cameraChannels = <int, MethodChannel>{};
30+
/// The per-camera handlers for messages that should be rebroadcast to
31+
/// clients as [CameraEvent]s.
32+
@visibleForTesting
33+
final Map<int, HostCameraMessageHandler> hostCameraHandlers =
34+
<int, HostCameraMessageHandler>{};
3235

3336
// The stream to receive frames from the native code.
3437
StreamSubscription<dynamic>? _platformImageStreamSubscription;
@@ -105,15 +108,8 @@ class CameraWindows extends CameraPlatform {
105108
int cameraId, {
106109
ImageFormatGroup imageFormatGroup = ImageFormatGroup.unknown,
107110
}) async {
108-
/// Creates channel for camera events.
109-
_cameraChannels.putIfAbsent(cameraId, () {
110-
final MethodChannel channel =
111-
MethodChannel('plugins.flutter.io/camera_windows/camera$cameraId');
112-
channel.setMethodCallHandler(
113-
(MethodCall call) => handleCameraMethodCall(call, cameraId),
114-
);
115-
return channel;
116-
});
111+
hostCameraHandlers.putIfAbsent(cameraId,
112+
() => HostCameraMessageHandler(cameraId, cameraEventStreamController));
117113

118114
final PlatformSize reply;
119115
try {
@@ -140,11 +136,7 @@ class CameraWindows extends CameraPlatform {
140136
await _hostApi.dispose(cameraId);
141137

142138
// Destroy method channel after camera is disposed to be able to handle last messages.
143-
if (_cameraChannels.containsKey(cameraId)) {
144-
final MethodChannel? cameraChannel = _cameraChannels[cameraId];
145-
cameraChannel?.setMethodCallHandler(null);
146-
_cameraChannels.remove(cameraId);
147-
}
139+
hostCameraHandlers.remove(cameraId)?.dispose();
148140
}
149141

150142
@override
@@ -398,33 +390,6 @@ class CameraWindows extends CameraPlatform {
398390
return Texture(textureId: cameraId);
399391
}
400392

401-
/// Converts messages received from the native platform into camera events.
402-
///
403-
/// This is only exposed for test purposes. It shouldn't be used by clients
404-
/// of the plugin as it may break or change at any time.
405-
@visibleForTesting
406-
Future<dynamic> handleCameraMethodCall(MethodCall call, int cameraId) async {
407-
switch (call.method) {
408-
case 'camera_closing':
409-
cameraEventStreamController.add(
410-
CameraClosingEvent(
411-
cameraId,
412-
),
413-
);
414-
case 'error':
415-
final Map<String, Object?> arguments =
416-
(call.arguments as Map<Object?, Object?>).cast<String, Object?>();
417-
cameraEventStreamController.add(
418-
CameraErrorEvent(
419-
cameraId,
420-
arguments['description']! as String,
421-
),
422-
);
423-
default:
424-
throw UnimplementedError();
425-
}
426-
}
427-
428393
/// Returns a [MediaSettings]'s Pigeon representation.
429394
PlatformMediaSettings _pigeonMediaSettings(MediaSettings? settings) {
430395
return PlatformMediaSettings(
@@ -467,3 +432,35 @@ class CameraWindows extends CameraPlatform {
467432
return PlatformResolutionPreset.max;
468433
}
469434
}
435+
436+
/// Callback handler for camera-level events from the platform host.
437+
@visibleForTesting
438+
class HostCameraMessageHandler implements CameraEventApi {
439+
/// Creates a new handler that listens for events from camera [cameraId], and
440+
/// broadcasts them to [streamController].
441+
HostCameraMessageHandler(this.cameraId, this.streamController) {
442+
CameraEventApi.setUp(this, messageChannelSuffix: cameraId.toString());
443+
}
444+
445+
/// Removes the handler for native messages.
446+
void dispose() {
447+
CameraEventApi.setUp(null, messageChannelSuffix: cameraId.toString());
448+
}
449+
450+
/// The camera ID this handler listens for events from.
451+
final int cameraId;
452+
453+
/// The controller used to broadcast camera events coming from the
454+
/// host platform.
455+
final StreamController<CameraEvent> streamController;
456+
457+
@override
458+
void error(String message) {
459+
streamController.add(CameraErrorEvent(cameraId, message));
460+
}
461+
462+
@override
463+
void cameraClosing() {
464+
streamController.add(CameraClosingEvent(cameraId));
465+
}
466+
}

0 commit comments

Comments
 (0)