diff --git a/packages/camera/camera_windows/CHANGELOG.md b/packages/camera/camera_windows/CHANGELOG.md index e9f281bd641e..6661f408e45c 100644 --- a/packages/camera/camera_windows/CHANGELOG.md +++ b/packages/camera/camera_windows/CHANGELOG.md @@ -1,5 +1,6 @@ -## NEXT +## 0.2.5+1 +* Updates C++ to Dart communication to use Pigeon. * Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. ## 0.2.5 diff --git a/packages/camera/camera_windows/lib/camera_windows.dart b/packages/camera/camera_windows/lib/camera_windows.dart index 6166c99333d2..bdbfc17dcf8e 100644 --- a/packages/camera/camera_windows/lib/camera_windows.dart +++ b/packages/camera/camera_windows/lib/camera_windows.dart @@ -27,8 +27,11 @@ class CameraWindows extends CameraPlatform { /// Interface for calling host-side code. final CameraApi _hostApi; - /// Camera specific method channels to allow communicating with specific cameras. - final Map _cameraChannels = {}; + /// The per-camera handlers for messages that should be rebroadcast to + /// clients as [CameraEvent]s. + @visibleForTesting + final Map hostCameraHandlers = + {}; // The stream to receive frames from the native code. StreamSubscription? _platformImageStreamSubscription; @@ -105,15 +108,8 @@ class CameraWindows extends CameraPlatform { int cameraId, { ImageFormatGroup imageFormatGroup = ImageFormatGroup.unknown, }) async { - /// Creates channel for camera events. - _cameraChannels.putIfAbsent(cameraId, () { - final MethodChannel channel = - MethodChannel('plugins.flutter.io/camera_windows/camera$cameraId'); - channel.setMethodCallHandler( - (MethodCall call) => handleCameraMethodCall(call, cameraId), - ); - return channel; - }); + hostCameraHandlers.putIfAbsent(cameraId, + () => HostCameraMessageHandler(cameraId, cameraEventStreamController)); final PlatformSize reply; try { @@ -140,11 +136,7 @@ class CameraWindows extends CameraPlatform { await _hostApi.dispose(cameraId); // Destroy method channel after camera is disposed to be able to handle last messages. - if (_cameraChannels.containsKey(cameraId)) { - final MethodChannel? cameraChannel = _cameraChannels[cameraId]; - cameraChannel?.setMethodCallHandler(null); - _cameraChannels.remove(cameraId); - } + hostCameraHandlers.remove(cameraId)?.dispose(); } @override @@ -398,33 +390,6 @@ class CameraWindows extends CameraPlatform { return Texture(textureId: cameraId); } - /// Converts messages received from the native platform into camera events. - /// - /// This is only exposed for test purposes. It shouldn't be used by clients - /// of the plugin as it may break or change at any time. - @visibleForTesting - Future handleCameraMethodCall(MethodCall call, int cameraId) async { - switch (call.method) { - case 'camera_closing': - cameraEventStreamController.add( - CameraClosingEvent( - cameraId, - ), - ); - case 'error': - final Map arguments = - (call.arguments as Map).cast(); - cameraEventStreamController.add( - CameraErrorEvent( - cameraId, - arguments['description']! as String, - ), - ); - default: - throw UnimplementedError(); - } - } - /// Returns a [MediaSettings]'s Pigeon representation. PlatformMediaSettings _pigeonMediaSettings(MediaSettings? settings) { return PlatformMediaSettings( @@ -467,3 +432,35 @@ class CameraWindows extends CameraPlatform { return PlatformResolutionPreset.max; } } + +/// Callback handler for camera-level events from the platform host. +@visibleForTesting +class HostCameraMessageHandler implements CameraEventApi { + /// Creates a new handler that listens for events from camera [cameraId], and + /// broadcasts them to [streamController]. + HostCameraMessageHandler(this.cameraId, this.streamController) { + CameraEventApi.setUp(this, messageChannelSuffix: cameraId.toString()); + } + + /// Removes the handler for native messages. + void dispose() { + CameraEventApi.setUp(null, messageChannelSuffix: cameraId.toString()); + } + + /// The camera ID this handler listens for events from. + final int cameraId; + + /// The controller used to broadcast camera events coming from the + /// host platform. + final StreamController streamController; + + @override + void error(String message) { + streamController.add(CameraErrorEvent(cameraId, message)); + } + + @override + void cameraClosing() { + streamController.add(CameraClosingEvent(cameraId)); + } +} diff --git a/packages/camera/camera_windows/lib/src/messages.g.dart b/packages/camera/camera_windows/lib/src/messages.g.dart index bb364aeb61ea..9930549183bb 100644 --- a/packages/camera/camera_windows/lib/src/messages.g.dart +++ b/packages/camera/camera_windows/lib/src/messages.g.dart @@ -1,7 +1,7 @@ // Copyright 2013 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Autogenerated from Pigeon (v21.0.0), do not edit directly. +// Autogenerated from Pigeon (v22.6.0), do not edit directly. // See also: https://pub.dev/packages/pigeon // ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers @@ -18,6 +18,17 @@ PlatformException _createConnectionError(String channelName) { ); } +List wrapResponse( + {Object? result, PlatformException? error, bool empty = false}) { + if (empty) { + return []; + } + if (error == null) { + return [result]; + } + return [error.code, error.message, error.details]; +} + /// Pigeon version of platform interface's ResolutionPreset. enum PlatformResolutionPreset { low, @@ -101,15 +112,18 @@ class _PigeonCodec extends StandardMessageCodec { const _PigeonCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is PlatformMediaSettings) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is PlatformResolutionPreset) { buffer.putUint8(129); - writeValue(buffer, value.encode()); - } else if (value is PlatformSize) { + writeValue(buffer, value.index); + } else if (value is PlatformMediaSettings) { buffer.putUint8(130); writeValue(buffer, value.encode()); - } else if (value is PlatformResolutionPreset) { + } else if (value is PlatformSize) { buffer.putUint8(131); - writeValue(buffer, value.index); + writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); } @@ -119,12 +133,12 @@ class _PigeonCodec extends StandardMessageCodec { Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { case 129: - return PlatformMediaSettings.decode(readValue(buffer)!); - case 130: - return PlatformSize.decode(readValue(buffer)!); - case 131: final int? value = readValue(buffer) as int?; return value == null ? null : PlatformResolutionPreset.values[value]; + case 130: + return PlatformMediaSettings.decode(readValue(buffer)!); + case 131: + return PlatformSize.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); } @@ -137,124 +151,124 @@ class CameraApi { /// BinaryMessenger will be used which routes to the host platform. CameraApi( {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : __pigeon_binaryMessenger = binaryMessenger, - __pigeon_messageChannelSuffix = + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; - final BinaryMessenger? __pigeon_binaryMessenger; + final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); - final String __pigeon_messageChannelSuffix; + final String pigeonVar_messageChannelSuffix; /// Returns the names of all of the available capture devices. - Future> getAvailableCameras() async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.camera_windows.CameraApi.getAvailableCameras$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + Future> getAvailableCameras() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_windows.CameraApi.getAvailableCameras$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send(null) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: __pigeon_replyList[0]! as String, - message: __pigeon_replyList[1] as String?, - details: __pigeon_replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); - } else if (__pigeon_replyList[0] == null) { + } else if (pigeonVar_replyList[0] == null) { throw PlatformException( code: 'null-error', message: 'Host platform returned null value for non-null return value.', ); } else { - return (__pigeon_replyList[0] as List?)!.cast(); + return (pigeonVar_replyList[0] as List?)!.cast(); } } /// Creates a camera instance for the given device name and settings. Future create(String cameraName, PlatformMediaSettings settings) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.camera_windows.CameraApi.create$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_windows.CameraApi.create$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = await __pigeon_channel + final List? pigeonVar_replyList = await pigeonVar_channel .send([cameraName, settings]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: __pigeon_replyList[0]! as String, - message: __pigeon_replyList[1] as String?, - details: __pigeon_replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); - } else if (__pigeon_replyList[0] == null) { + } else if (pigeonVar_replyList[0] == null) { throw PlatformException( code: 'null-error', message: 'Host platform returned null value for non-null return value.', ); } else { - return (__pigeon_replyList[0] as int?)!; + return (pigeonVar_replyList[0] as int?)!; } } /// Initializes a camera, and returns the size of its preview. Future initialize(int cameraId) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.camera_windows.CameraApi.initialize$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_windows.CameraApi.initialize$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([cameraId]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([cameraId]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: __pigeon_replyList[0]! as String, - message: __pigeon_replyList[1] as String?, - details: __pigeon_replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); - } else if (__pigeon_replyList[0] == null) { + } else if (pigeonVar_replyList[0] == null) { throw PlatformException( code: 'null-error', message: 'Host platform returned null value for non-null return value.', ); } else { - return (__pigeon_replyList[0] as PlatformSize?)!; + return (pigeonVar_replyList[0] as PlatformSize?)!; } } /// Disposes a camera that is no longer in use. Future dispose(int cameraId) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.camera_windows.CameraApi.dispose$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_windows.CameraApi.dispose$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([cameraId]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([cameraId]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: __pigeon_replyList[0]! as String, - message: __pigeon_replyList[1] as String?, - details: __pigeon_replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { return; @@ -264,53 +278,53 @@ class CameraApi { /// Takes a picture with the given camera, and returns the path to the /// resulting file. Future takePicture(int cameraId) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.camera_windows.CameraApi.takePicture$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_windows.CameraApi.takePicture$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([cameraId]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([cameraId]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: __pigeon_replyList[0]! as String, - message: __pigeon_replyList[1] as String?, - details: __pigeon_replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); - } else if (__pigeon_replyList[0] == null) { + } else if (pigeonVar_replyList[0] == null) { throw PlatformException( code: 'null-error', message: 'Host platform returned null value for non-null return value.', ); } else { - return (__pigeon_replyList[0] as String?)!; + return (pigeonVar_replyList[0] as String?)!; } } /// Starts recording video with the given camera. Future startVideoRecording(int cameraId) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.camera_windows.CameraApi.startVideoRecording$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_windows.CameraApi.startVideoRecording$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([cameraId]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([cameraId]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: __pigeon_replyList[0]! as String, - message: __pigeon_replyList[1] as String?, - details: __pigeon_replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { return; @@ -320,53 +334,53 @@ class CameraApi { /// Finishes recording video with the given camera, and returns the path to /// the resulting file. Future stopVideoRecording(int cameraId) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.camera_windows.CameraApi.stopVideoRecording$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_windows.CameraApi.stopVideoRecording$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([cameraId]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([cameraId]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: __pigeon_replyList[0]! as String, - message: __pigeon_replyList[1] as String?, - details: __pigeon_replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); - } else if (__pigeon_replyList[0] == null) { + } else if (pigeonVar_replyList[0] == null) { throw PlatformException( code: 'null-error', message: 'Host platform returned null value for non-null return value.', ); } else { - return (__pigeon_replyList[0] as String?)!; + return (pigeonVar_replyList[0] as String?)!; } } /// Starts the image stream for the given camera. Future startImageStream(int cameraId) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.camera_windows.CameraApi.startImageStream$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_windows.CameraApi.startImageStream$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([cameraId]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([cameraId]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: __pigeon_replyList[0]! as String, - message: __pigeon_replyList[1] as String?, - details: __pigeon_replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { return; @@ -375,23 +389,23 @@ class CameraApi { /// Stops the image stream for the given camera. Future stopImageStream(int cameraId) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.camera_windows.CameraApi.stopImageStream$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_windows.CameraApi.stopImageStream$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([cameraId]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([cameraId]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: __pigeon_replyList[0]! as String, - message: __pigeon_replyList[1] as String?, - details: __pigeon_replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { return; @@ -400,23 +414,23 @@ class CameraApi { /// Starts the preview stream for the given camera. Future pausePreview(int cameraId) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.camera_windows.CameraApi.pausePreview$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_windows.CameraApi.pausePreview$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([cameraId]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([cameraId]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: __pigeon_replyList[0]! as String, - message: __pigeon_replyList[1] as String?, - details: __pigeon_replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { return; @@ -425,26 +439,97 @@ class CameraApi { /// Resumes the preview stream for the given camera. Future resumePreview(int cameraId) async { - final String __pigeon_channelName = - 'dev.flutter.pigeon.camera_windows.CameraApi.resumePreview$__pigeon_messageChannelSuffix'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.camera_windows.CameraApi.resumePreview$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([cameraId]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([cameraId]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: __pigeon_replyList[0]! as String, - message: __pigeon_replyList[1] as String?, - details: __pigeon_replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { return; } } } + +abstract class CameraEventApi { + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + /// Called when the camera instance is closing on the native side. + void cameraClosing(); + + /// Called when a camera error occurs on the native side. + void error(String errorMessage); + + static void setUp( + CameraEventApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.camera_windows.CameraEventApi.cameraClosing$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + try { + api.cameraClosing(); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.camera_windows.CameraEventApi.error$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.camera_windows.CameraEventApi.error was null.'); + final List args = (message as List?)!; + final String? arg_errorMessage = (args[0] as String?); + assert(arg_errorMessage != null, + 'Argument for dev.flutter.pigeon.camera_windows.CameraEventApi.error was null, expected non-null String.'); + try { + api.error(arg_errorMessage!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } +} diff --git a/packages/camera/camera_windows/pigeons/messages.dart b/packages/camera/camera_windows/pigeons/messages.dart index a56a93c8353a..d0970af423ac 100644 --- a/packages/camera/camera_windows/pigeons/messages.dart +++ b/packages/camera/camera_windows/pigeons/messages.dart @@ -86,3 +86,12 @@ abstract class CameraApi { @async void resumePreview(int cameraId); } + +@FlutterApi() +abstract class CameraEventApi { + /// Called when the camera instance is closing on the native side. + void cameraClosing(); + + /// Called when a camera error occurs on the native side. + void error(String errorMessage); +} diff --git a/packages/camera/camera_windows/pubspec.yaml b/packages/camera/camera_windows/pubspec.yaml index 4ad68786edf3..2ba530a48448 100644 --- a/packages/camera/camera_windows/pubspec.yaml +++ b/packages/camera/camera_windows/pubspec.yaml @@ -2,7 +2,7 @@ name: camera_windows description: A Flutter plugin for getting information about and controlling the camera on Windows. repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_windows issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22 -version: 0.2.5 +version: 0.2.5+1 environment: sdk: ^3.3.0 @@ -29,7 +29,7 @@ dev_dependencies: flutter_test: sdk: flutter mockito: ^5.4.4 - pigeon: ^21.0.0 + pigeon: ^22.6.0 topics: - camera diff --git a/packages/camera/camera_windows/test/camera_windows_test.dart b/packages/camera/camera_windows/test/camera_windows_test.dart index ca7e7eb99448..7d21af5f7824 100644 --- a/packages/camera/camera_windows/test/camera_windows_test.dart +++ b/packages/camera/camera_windows/test/camera_windows_test.dart @@ -218,12 +218,9 @@ void main() { // Emit test events final CameraClosingEvent event = CameraClosingEvent(cameraId); - await plugin.handleCameraMethodCall( - MethodCall('camera_closing', event.toJson()), cameraId); - await plugin.handleCameraMethodCall( - MethodCall('camera_closing', event.toJson()), cameraId); - await plugin.handleCameraMethodCall( - MethodCall('camera_closing', event.toJson()), cameraId); + plugin.hostCameraHandlers[cameraId]!.cameraClosing(); + plugin.hostCameraHandlers[cameraId]!.cameraClosing(); + plugin.hostCameraHandlers[cameraId]!.cameraClosing(); // Assert expect(await streamQueue.next, event); @@ -242,14 +239,11 @@ void main() { StreamQueue(errorStream); // Emit test events - final CameraErrorEvent event = - CameraErrorEvent(cameraId, 'Error Description'); - await plugin.handleCameraMethodCall( - MethodCall('error', event.toJson()), cameraId); - await plugin.handleCameraMethodCall( - MethodCall('error', event.toJson()), cameraId); - await plugin.handleCameraMethodCall( - MethodCall('error', event.toJson()), cameraId); + const String errorMessage = 'Error Description'; + final CameraErrorEvent event = CameraErrorEvent(cameraId, errorMessage); + plugin.hostCameraHandlers[cameraId]!.error(errorMessage); + plugin.hostCameraHandlers[cameraId]!.error(errorMessage); + plugin.hostCameraHandlers[cameraId]!.error(errorMessage); // Assert expect(await streamQueue.next, event); @@ -491,15 +485,6 @@ void main() { expect((widget as Texture).textureId, cameraId); }); - test('Should throw UnimplementedError when handling unknown method', () { - final CameraWindows plugin = CameraWindows(api: mockApi); - - expect( - () => plugin.handleCameraMethodCall( - const MethodCall('unknown_method'), 1), - throwsA(isA())); - }); - test('Should get the max zoom level', () async { // Act final double maxZoomLevel = await plugin.getMaxZoomLevel(cameraId); diff --git a/packages/camera/camera_windows/test/camera_windows_test.mocks.dart b/packages/camera/camera_windows/test/camera_windows_test.mocks.dart index d55db4a6bd56..7e22e1739188 100644 --- a/packages/camera/camera_windows/test/camera_windows_test.mocks.dart +++ b/packages/camera/camera_windows/test/camera_windows_test.mocks.dart @@ -3,11 +3,11 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i3; +import 'dart:async' as _i4; import 'package:camera_windows/src/messages.g.dart' as _i2; import 'package:mockito/mockito.dart' as _i1; -import 'package:mockito/src/dummies.dart' as _i4; +import 'package:mockito/src/dummies.dart' as _i3; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -37,17 +37,30 @@ class _FakePlatformSize_0 extends _i1.SmartFake implements _i2.PlatformSize { /// See the documentation for Mockito's code generation for more information. class MockCameraApi extends _i1.Mock implements _i2.CameraApi { @override - _i3.Future> getAvailableCameras() => (super.noSuchMethod( + String get pigeonVar_messageChannelSuffix => (super.noSuchMethod( + Invocation.getter(#pigeonVar_messageChannelSuffix), + returnValue: _i3.dummyValue( + this, + Invocation.getter(#pigeonVar_messageChannelSuffix), + ), + returnValueForMissingStub: _i3.dummyValue( + this, + Invocation.getter(#pigeonVar_messageChannelSuffix), + ), + ) as String); + + @override + _i4.Future> getAvailableCameras() => (super.noSuchMethod( Invocation.method( #getAvailableCameras, [], ), - returnValue: _i3.Future>.value([]), - returnValueForMissingStub: _i3.Future>.value([]), - ) as _i3.Future>); + returnValue: _i4.Future>.value([]), + returnValueForMissingStub: _i4.Future>.value([]), + ) as _i4.Future>); @override - _i3.Future create( + _i4.Future create( String? cameraName, _i2.PlatformMediaSettings? settings, ) => @@ -59,17 +72,17 @@ class MockCameraApi extends _i1.Mock implements _i2.CameraApi { settings, ], ), - returnValue: _i3.Future.value(0), - returnValueForMissingStub: _i3.Future.value(0), - ) as _i3.Future); + returnValue: _i4.Future.value(0), + returnValueForMissingStub: _i4.Future.value(0), + ) as _i4.Future); @override - _i3.Future<_i2.PlatformSize> initialize(int? cameraId) => (super.noSuchMethod( + _i4.Future<_i2.PlatformSize> initialize(int? cameraId) => (super.noSuchMethod( Invocation.method( #initialize, [cameraId], ), - returnValue: _i3.Future<_i2.PlatformSize>.value(_FakePlatformSize_0( + returnValue: _i4.Future<_i2.PlatformSize>.value(_FakePlatformSize_0( this, Invocation.method( #initialize, @@ -77,32 +90,32 @@ class MockCameraApi extends _i1.Mock implements _i2.CameraApi { ), )), returnValueForMissingStub: - _i3.Future<_i2.PlatformSize>.value(_FakePlatformSize_0( + _i4.Future<_i2.PlatformSize>.value(_FakePlatformSize_0( this, Invocation.method( #initialize, [cameraId], ), )), - ) as _i3.Future<_i2.PlatformSize>); + ) as _i4.Future<_i2.PlatformSize>); @override - _i3.Future dispose(int? cameraId) => (super.noSuchMethod( + _i4.Future dispose(int? cameraId) => (super.noSuchMethod( Invocation.method( #dispose, [cameraId], ), - returnValue: _i3.Future.value(), - returnValueForMissingStub: _i3.Future.value(), - ) as _i3.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i3.Future takePicture(int? cameraId) => (super.noSuchMethod( + _i4.Future takePicture(int? cameraId) => (super.noSuchMethod( Invocation.method( #takePicture, [cameraId], ), - returnValue: _i3.Future.value(_i4.dummyValue( + returnValue: _i4.Future.value(_i3.dummyValue( this, Invocation.method( #takePicture, @@ -110,32 +123,32 @@ class MockCameraApi extends _i1.Mock implements _i2.CameraApi { ), )), returnValueForMissingStub: - _i3.Future.value(_i4.dummyValue( + _i4.Future.value(_i3.dummyValue( this, Invocation.method( #takePicture, [cameraId], ), )), - ) as _i3.Future); + ) as _i4.Future); @override - _i3.Future startVideoRecording(int? cameraId) => (super.noSuchMethod( + _i4.Future startVideoRecording(int? cameraId) => (super.noSuchMethod( Invocation.method( #startVideoRecording, [cameraId], ), - returnValue: _i3.Future.value(), - returnValueForMissingStub: _i3.Future.value(), - ) as _i3.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i3.Future stopVideoRecording(int? cameraId) => (super.noSuchMethod( + _i4.Future stopVideoRecording(int? cameraId) => (super.noSuchMethod( Invocation.method( #stopVideoRecording, [cameraId], ), - returnValue: _i3.Future.value(_i4.dummyValue( + returnValue: _i4.Future.value(_i3.dummyValue( this, Invocation.method( #stopVideoRecording, @@ -143,32 +156,52 @@ class MockCameraApi extends _i1.Mock implements _i2.CameraApi { ), )), returnValueForMissingStub: - _i3.Future.value(_i4.dummyValue( + _i4.Future.value(_i3.dummyValue( this, Invocation.method( #stopVideoRecording, [cameraId], ), )), - ) as _i3.Future); + ) as _i4.Future); + + @override + _i4.Future startImageStream(int? cameraId) => (super.noSuchMethod( + Invocation.method( + #startImageStream, + [cameraId], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future stopImageStream(int? cameraId) => (super.noSuchMethod( + Invocation.method( + #stopImageStream, + [cameraId], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i3.Future pausePreview(int? cameraId) => (super.noSuchMethod( + _i4.Future pausePreview(int? cameraId) => (super.noSuchMethod( Invocation.method( #pausePreview, [cameraId], ), - returnValue: _i3.Future.value(), - returnValueForMissingStub: _i3.Future.value(), - ) as _i3.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i3.Future resumePreview(int? cameraId) => (super.noSuchMethod( + _i4.Future resumePreview(int? cameraId) => (super.noSuchMethod( Invocation.method( #resumePreview, [cameraId], ), - returnValue: _i3.Future.value(), - returnValueForMissingStub: _i3.Future.value(), - ) as _i3.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); } diff --git a/packages/camera/camera_windows/windows/camera.cpp b/packages/camera/camera_windows/windows/camera.cpp index 7cfc5708ef48..13bf3b3efae3 100644 --- a/packages/camera/camera_windows/windows/camera.cpp +++ b/packages/camera/camera_windows/windows/camera.cpp @@ -5,15 +5,6 @@ #include "camera.h" namespace camera_windows { -using flutter::EncodableList; -using flutter::EncodableMap; -using flutter::EncodableValue; - -// Camera channel events. -constexpr char kCameraMethodChannelBaseName[] = - "plugins.flutter.io/camera_windows/camera"; -constexpr char kCameraClosingEvent[] = "camera_closing"; -constexpr char kErrorEvent[] = "error"; // Camera error codes constexpr char kCameraAccessDenied[] = "CameraAccessDenied"; @@ -177,22 +168,16 @@ void CameraImpl::SendErrorForPendingResults(const std::string& error_code, pending_results_.clear(); } -MethodChannel<>* CameraImpl::GetMethodChannel() { +CameraEventApi* CameraImpl::GetEventApi() { assert(messenger_); assert(camera_id_); - // Use existing channel if initialized - if (camera_channel_) { - return camera_channel_.get(); + if (!event_api_) { + std::string suffix = std::to_string(camera_id_); + event_api_ = std::make_unique(messenger_, suffix); } - auto channel_name = - std::string(kCameraMethodChannelBaseName) + std::to_string(camera_id_); - - camera_channel_ = std::make_unique>( - messenger_, channel_name, &flutter::StandardMethodCodec::GetInstance()); - - return camera_channel_.get(); + return event_api_.get(); } void CameraImpl::OnCreateCaptureEngineSucceeded(int64_t texture_id) { @@ -326,12 +311,11 @@ void CameraImpl::OnTakePictureFailed(CameraResult result, void CameraImpl::OnCaptureError(CameraResult result, const std::string& error) { if (messenger_ && camera_id_ >= 0) { - auto channel = GetMethodChannel(); - - std::unique_ptr message_data = - std::make_unique(EncodableMap( - {{EncodableValue("description"), EncodableValue(error)}})); - channel->InvokeMethod(kErrorEvent, std::move(message_data)); + GetEventApi()->Error( + error, + // TODO(stuartmorgan): Replace with an event channel, since that's how + // these calls are used. Given that use case, ignore responses. + []() {}, [](const FlutterError& error) {}); } std::string error_code = GetErrorCode(result); @@ -340,9 +324,9 @@ void CameraImpl::OnCaptureError(CameraResult result, const std::string& error) { void CameraImpl::OnCameraClosing() { if (messenger_ && camera_id_ >= 0) { - auto channel = GetMethodChannel(); - channel->InvokeMethod(kCameraClosingEvent, - std::move(std::make_unique())); + // TODO(stuartmorgan): Replace with an event channel, since that's how + // these calls are used. Given that use case, ignore responses. + GetEventApi()->CameraClosing([]() {}, [](const FlutterError& error) {}); } } diff --git a/packages/camera/camera_windows/windows/camera.h b/packages/camera/camera_windows/windows/camera.h index b4a32d7dc34f..2a44ad2ccf62 100644 --- a/packages/camera/camera_windows/windows/camera.h +++ b/packages/camera/camera_windows/windows/camera.h @@ -5,21 +5,15 @@ #ifndef PACKAGES_CAMERA_CAMERA_WINDOWS_WINDOWS_CAMERA_H_ #define PACKAGES_CAMERA_CAMERA_WINDOWS_WINDOWS_CAMERA_H_ -#include -#include - #include #include #include #include "capture_controller.h" +#include "messages.g.h" namespace camera_windows { -using flutter::EncodableMap; -using flutter::MethodChannel; -using flutter::MethodResult; - // A set of result types that are stored // for processing asynchronous commands. enum class PendingResultType { @@ -193,8 +187,8 @@ class CameraImpl : public Camera { // Sends camera closing message to the cameras method channel. void OnCameraClosing(); - // Initializes method channel instance and returns pointer it. - MethodChannel<>* GetMethodChannel(); + // Returns the FlutterApi instance used to communicate camera events. + CameraEventApi* GetEventApi(); // Finds pending void result by type. // @@ -236,7 +230,7 @@ class CameraImpl : public Camera { std::map pending_results_; std::unique_ptr capture_controller_; - std::unique_ptr> camera_channel_; + std::unique_ptr event_api_; flutter::BinaryMessenger* messenger_ = nullptr; int64_t camera_id_ = -1; std::string device_id_; diff --git a/packages/camera/camera_windows/windows/messages.g.cpp b/packages/camera/camera_windows/windows/messages.g.cpp index 08a91943f546..724d42037480 100644 --- a/packages/camera/camera_windows/windows/messages.g.cpp +++ b/packages/camera/camera_windows/windows/messages.g.cpp @@ -1,7 +1,7 @@ // Copyright 2013 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Autogenerated from Pigeon (v21.0.0), do not edit directly. +// Autogenerated from Pigeon (v22.6.0), do not edit directly. // See also: https://pub.dev/packages/pigeon #undef _HAS_EXCEPTIONS @@ -127,15 +127,16 @@ PlatformMediaSettings PlatformMediaSettings::FromEncodableList( std::get(list[4])); auto& encodable_frames_per_second = list[1]; if (!encodable_frames_per_second.IsNull()) { - decoded.set_frames_per_second(encodable_frames_per_second.LongValue()); + decoded.set_frames_per_second( + std::get(encodable_frames_per_second)); } auto& encodable_video_bitrate = list[2]; if (!encodable_video_bitrate.IsNull()) { - decoded.set_video_bitrate(encodable_video_bitrate.LongValue()); + decoded.set_video_bitrate(std::get(encodable_video_bitrate)); } auto& encodable_audio_bitrate = list[3]; if (!encodable_audio_bitrate.IsNull()) { - decoded.set_audio_bitrate(encodable_audio_bitrate.LongValue()); + decoded.set_audio_bitrate(std::get(encodable_audio_bitrate)); } return decoded; } @@ -166,18 +167,12 @@ PlatformSize PlatformSize::FromEncodableList(const EncodableList& list) { return decoded; } -PigeonCodecSerializer::PigeonCodecSerializer() {} +PigeonInternalCodecSerializer::PigeonInternalCodecSerializer() {} -EncodableValue PigeonCodecSerializer::ReadValueOfType( +EncodableValue PigeonInternalCodecSerializer::ReadValueOfType( uint8_t type, flutter::ByteStreamReader* stream) const { switch (type) { - case 129: - return CustomEncodableValue(PlatformMediaSettings::FromEncodableList( - std::get(ReadValue(stream)))); - case 130: - return CustomEncodableValue(PlatformSize::FromEncodableList( - std::get(ReadValue(stream)))); - case 131: { + case 129: { const auto& encodable_enum_arg = ReadValue(stream); const int64_t enum_arg_value = encodable_enum_arg.IsNull() ? 0 : encodable_enum_arg.LongValue(); @@ -186,17 +181,32 @@ EncodableValue PigeonCodecSerializer::ReadValueOfType( : CustomEncodableValue( static_cast(enum_arg_value)); } + case 130: { + return CustomEncodableValue(PlatformMediaSettings::FromEncodableList( + std::get(ReadValue(stream)))); + } + case 131: { + return CustomEncodableValue(PlatformSize::FromEncodableList( + std::get(ReadValue(stream)))); + } default: return flutter::StandardCodecSerializer::ReadValueOfType(type, stream); } } -void PigeonCodecSerializer::WriteValue( +void PigeonInternalCodecSerializer::WriteValue( const EncodableValue& value, flutter::ByteStreamWriter* stream) const { if (const CustomEncodableValue* custom_value = std::get_if(&value)) { - if (custom_value->type() == typeid(PlatformMediaSettings)) { + if (custom_value->type() == typeid(PlatformResolutionPreset)) { stream->WriteByte(129); + WriteValue(EncodableValue(static_cast( + std::any_cast(*custom_value))), + stream); + return; + } + if (custom_value->type() == typeid(PlatformMediaSettings)) { + stream->WriteByte(130); WriteValue( EncodableValue(std::any_cast(*custom_value) .ToEncodableList()), @@ -204,20 +214,13 @@ void PigeonCodecSerializer::WriteValue( return; } if (custom_value->type() == typeid(PlatformSize)) { - stream->WriteByte(130); + stream->WriteByte(131); WriteValue( EncodableValue( std::any_cast(*custom_value).ToEncodableList()), stream); return; } - if (custom_value->type() == typeid(PlatformResolutionPreset)) { - stream->WriteByte(131); - WriteValue(EncodableValue(static_cast( - std::any_cast(*custom_value))), - stream); - return; - } } flutter::StandardCodecSerializer::WriteValue(value, stream); } @@ -225,7 +228,7 @@ void PigeonCodecSerializer::WriteValue( /// The codec used by CameraApi. const flutter::StandardMessageCodec& CameraApi::GetCodec() { return flutter::StandardMessageCodec::GetInstance( - &PigeonCodecSerializer::GetInstance()); + &PigeonInternalCodecSerializer::GetInstance()); } // Sets up an instance of `CameraApi` to handle messages through the @@ -653,4 +656,88 @@ EncodableValue CameraApi::WrapError(const FlutterError& error) { error.details()}); } +// Generated class from Pigeon that represents Flutter messages that can be +// called from C++. +CameraEventApi::CameraEventApi(flutter::BinaryMessenger* binary_messenger) + : binary_messenger_(binary_messenger), message_channel_suffix_("") {} + +CameraEventApi::CameraEventApi(flutter::BinaryMessenger* binary_messenger, + const std::string& message_channel_suffix) + : binary_messenger_(binary_messenger), + message_channel_suffix_(message_channel_suffix.length() > 0 + ? std::string(".") + message_channel_suffix + : "") {} + +const flutter::StandardMessageCodec& CameraEventApi::GetCodec() { + return flutter::StandardMessageCodec::GetInstance( + &PigeonInternalCodecSerializer::GetInstance()); +} + +void CameraEventApi::CameraClosing( + std::function&& on_success, + std::function&& on_error) { + const std::string channel_name = + "dev.flutter.pigeon.camera_windows.CameraEventApi.cameraClosing" + + message_channel_suffix_; + BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); + EncodableValue encoded_api_arguments = EncodableValue(); + channel.Send( + encoded_api_arguments, [channel_name, on_success = std::move(on_success), + on_error = std::move(on_error)]( + const uint8_t* reply, size_t reply_size) { + std::unique_ptr response = + GetCodec().DecodeMessage(reply, reply_size); + const auto& encodable_return_value = *response; + const auto* list_return_value = + std::get_if(&encodable_return_value); + if (list_return_value) { + if (list_return_value->size() > 1) { + on_error( + FlutterError(std::get(list_return_value->at(0)), + std::get(list_return_value->at(1)), + list_return_value->at(2))); + } else { + on_success(); + } + } else { + on_error(CreateConnectionError(channel_name)); + } + }); +} + +void CameraEventApi::Error( + const std::string& error_message_arg, + std::function&& on_success, + std::function&& on_error) { + const std::string channel_name = + "dev.flutter.pigeon.camera_windows.CameraEventApi.error" + + message_channel_suffix_; + BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); + EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ + EncodableValue(error_message_arg), + }); + channel.Send( + encoded_api_arguments, [channel_name, on_success = std::move(on_success), + on_error = std::move(on_error)]( + const uint8_t* reply, size_t reply_size) { + std::unique_ptr response = + GetCodec().DecodeMessage(reply, reply_size); + const auto& encodable_return_value = *response; + const auto* list_return_value = + std::get_if(&encodable_return_value); + if (list_return_value) { + if (list_return_value->size() > 1) { + on_error( + FlutterError(std::get(list_return_value->at(0)), + std::get(list_return_value->at(1)), + list_return_value->at(2))); + } else { + on_success(); + } + } else { + on_error(CreateConnectionError(channel_name)); + } + }); +} + } // namespace camera_windows diff --git a/packages/camera/camera_windows/windows/messages.g.h b/packages/camera/camera_windows/windows/messages.g.h index e4e42ce9e50b..9dcb6fab7d14 100644 --- a/packages/camera/camera_windows/windows/messages.g.h +++ b/packages/camera/camera_windows/windows/messages.g.h @@ -1,7 +1,7 @@ // Copyright 2013 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Autogenerated from Pigeon (v21.0.0), do not edit directly. +// Autogenerated from Pigeon (v22.6.0), do not edit directly. // See also: https://pub.dev/packages/pigeon #ifndef PIGEON_MESSAGES_G_H_ @@ -52,6 +52,7 @@ class ErrorOr { private: friend class CameraApi; + friend class CameraEventApi; ErrorOr() = default; T TakeValue() && { return std::get(std::move(v_)); } @@ -106,7 +107,8 @@ class PlatformMediaSettings { const flutter::EncodableList& list); flutter::EncodableList ToEncodableList() const; friend class CameraApi; - friend class PigeonCodecSerializer; + friend class CameraEventApi; + friend class PigeonInternalCodecSerializer; PlatformResolutionPreset resolution_preset_; std::optional frames_per_second_; std::optional video_bitrate_; @@ -132,16 +134,17 @@ class PlatformSize { static PlatformSize FromEncodableList(const flutter::EncodableList& list); flutter::EncodableList ToEncodableList() const; friend class CameraApi; - friend class PigeonCodecSerializer; + friend class CameraEventApi; + friend class PigeonInternalCodecSerializer; double width_; double height_; }; -class PigeonCodecSerializer : public flutter::StandardCodecSerializer { +class PigeonInternalCodecSerializer : public flutter::StandardCodecSerializer { public: - PigeonCodecSerializer(); - inline static PigeonCodecSerializer& GetInstance() { - static PigeonCodecSerializer sInstance; + PigeonInternalCodecSerializer(); + inline static PigeonInternalCodecSerializer& GetInstance() { + static PigeonInternalCodecSerializer sInstance; return sInstance; } @@ -216,5 +219,26 @@ class CameraApi { protected: CameraApi() = default; }; +// Generated class from Pigeon that represents Flutter messages that can be +// called from C++. +class CameraEventApi { + public: + CameraEventApi(flutter::BinaryMessenger* binary_messenger); + CameraEventApi(flutter::BinaryMessenger* binary_messenger, + const std::string& message_channel_suffix); + static const flutter::StandardMessageCodec& GetCodec(); + // Called when the camera instance is closing on the native side. + void CameraClosing(std::function&& on_success, + std::function&& on_error); + // Called when a camera error occurs on the native side. + void Error(const std::string& error_message, + std::function&& on_success, + std::function&& on_error); + + private: + flutter::BinaryMessenger* binary_messenger_; + std::string message_channel_suffix_; +}; + } // namespace camera_windows #endif // PIGEON_MESSAGES_G_H_