Skip to content

Commit

Permalink
[pigeon] fixes event channel dart instance name usage and adds test (#…
Browse files Browse the repository at this point in the history
…8483)

fixes event channel dart instance name usage and adds test
fixes flutter/flutter#161813
  • Loading branch information
tarrinneal authored Jan 23, 2025
1 parent ac08525 commit 894640f
Show file tree
Hide file tree
Showing 14 changed files with 197 additions and 10 deletions.
4 changes: 4 additions & 0 deletions packages/pigeon/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 22.7.4

* [dart] Fixes bug with multi-instance event channel support.

## 22.7.3

* Adds compatibility with `analyzer` 7.x.*.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ Stream<PlatformEvent> streamEvents({String instanceName = ''}) {
if (instanceName.isNotEmpty) {
instanceName = '.$instanceName';
}
const EventChannel streamEventsChannel = EventChannel(
'dev.flutter.pigeon.pigeon_example_package.EventChannelMethods.streamEvents',
final EventChannel streamEventsChannel = EventChannel(
'dev.flutter.pigeon.pigeon_example_package.EventChannelMethods.streamEvents$instanceName',
pigeonMethodCodec);
return streamEventsChannel.receiveBroadcastStream().map((dynamic event) {
return event as PlatformEvent;
Expand Down
4 changes: 2 additions & 2 deletions packages/pigeon/lib/dart_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -556,8 +556,8 @@ final BinaryMessenger? ${varNamePrefix}binaryMessenger;
if (instanceName.isNotEmpty) {
instanceName = '.\$instanceName';
}
const EventChannel ${func.name}Channel =
EventChannel('${makeChannelName(api, func, dartPackageName)}', $_pigeonMethodChannelCodec);
final EventChannel ${func.name}Channel =
EventChannel('${makeChannelName(api, func, dartPackageName)}\$instanceName', $_pigeonMethodChannelCodec);
return ${func.name}Channel.receiveBroadcastStream().map((dynamic event) {
return event as ${func.returnType.baseName};
});
Expand Down
2 changes: 1 addition & 1 deletion packages/pigeon/lib/generator_tools.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import 'ast.dart';
/// The current version of pigeon.
///
/// This must match the version in pubspec.yaml.
const String pigeonVersion = '22.7.3';
const String pigeonVersion = '22.7.4';

/// Read all the content from [stdin] to a String.
String readStdin() {
Expand Down
1 change: 1 addition & 0 deletions packages/pigeon/pigeons/event_channel_tests.dart
Original file line number Diff line number Diff line change
Expand Up @@ -141,4 +141,5 @@ class ClassEvent extends PlatformEvent {
abstract class EventChannelMethods {
int streamInts();
PlatformEvent streamEvents();
int streamConsistentNumbers();
}
Original file line number Diff line number Diff line change
Expand Up @@ -2865,6 +2865,7 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) {
TargetGenerator.kotlin,
TargetGenerator.swift
];

testWidgets('event channel sends continuous ints', (_) async {
final Stream<int> events = streamInts();
final List<int> listEvents = await events.toList();
Expand Down Expand Up @@ -2912,6 +2913,24 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) {
});
await completer.future;
}, skip: !eventChannelSupported.contains(targetGenerator));

testWidgets('event channels handle multiple instances', (_) async {
final Completer<void> completer1 = Completer<void>();
final Completer<void> completer2 = Completer<void>();
final Stream<int> events1 = streamConsistentNumbers(instanceName: '1');
final Stream<int> events2 = streamConsistentNumbers(instanceName: '2');

events1.listen((int event) {
expect(event, 1);
}).onDone(() => completer1.complete());

events2.listen((int event) {
expect(event, 2);
}).onDone(() => completer2.complete());

await completer1.future;
await completer2.future;
}, skip: !eventChannelSupported.contains(targetGenerator));
}

class _FlutterApiTestImplementation implements FlutterIntegrationCoreApi {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -432,8 +432,8 @@ Stream<int> streamInts({String instanceName = ''}) {
if (instanceName.isNotEmpty) {
instanceName = '.$instanceName';
}
const EventChannel streamIntsChannel = EventChannel(
'dev.flutter.pigeon.pigeon_integration_tests.EventChannelMethods.streamInts',
final EventChannel streamIntsChannel = EventChannel(
'dev.flutter.pigeon.pigeon_integration_tests.EventChannelMethods.streamInts$instanceName',
pigeonMethodCodec);
return streamIntsChannel.receiveBroadcastStream().map((dynamic event) {
return event as int;
Expand All @@ -444,10 +444,24 @@ Stream<PlatformEvent> streamEvents({String instanceName = ''}) {
if (instanceName.isNotEmpty) {
instanceName = '.$instanceName';
}
const EventChannel streamEventsChannel = EventChannel(
'dev.flutter.pigeon.pigeon_integration_tests.EventChannelMethods.streamEvents',
final EventChannel streamEventsChannel = EventChannel(
'dev.flutter.pigeon.pigeon_integration_tests.EventChannelMethods.streamEvents$instanceName',
pigeonMethodCodec);
return streamEventsChannel.receiveBroadcastStream().map((dynamic event) {
return event as PlatformEvent;
});
}

Stream<int> streamConsistentNumbers({String instanceName = ''}) {
if (instanceName.isNotEmpty) {
instanceName = '.$instanceName';
}
final EventChannel streamConsistentNumbersChannel = EventChannel(
'dev.flutter.pigeon.pigeon_integration_tests.EventChannelMethods.streamConsistentNumbers$instanceName',
pigeonMethodCodec);
return streamConsistentNumbersChannel
.receiveBroadcastStream()
.map((dynamic event) {
return event as int;
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -470,3 +470,22 @@ abstract class StreamEventsStreamHandler : PigeonEventChannelWrapper<PlatformEve
}
}
}

abstract class StreamConsistentNumbersStreamHandler : PigeonEventChannelWrapper<Long> {
companion object {
fun register(
messenger: BinaryMessenger,
streamHandler: StreamConsistentNumbersStreamHandler,
instanceName: String = ""
) {
var channelName: String =
"dev.flutter.pigeon.pigeon_integration_tests.EventChannelMethods.streamConsistentNumbers"
if (instanceName.isNotEmpty()) {
channelName += ".$instanceName"
}
val internalStreamHandler = PigeonStreamHandler<Long>(streamHandler)
EventChannel(messenger, channelName, EventChannelTestsPigeonMethodCodec)
.setStreamHandler(internalStreamHandler)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ class TestPlugin : FlutterPlugin, HostIntegrationCoreApi {

StreamEventsStreamHandler.register(binding.binaryMessenger, SendClass)
StreamIntsStreamHandler.register(binding.binaryMessenger, SendInts)
StreamConsistentNumbersStreamHandler.register(
binding.binaryMessenger, SendConsistentNumbers(1), "1")
StreamConsistentNumbersStreamHandler.register(
binding.binaryMessenger, SendConsistentNumbers(2), "2")
}

override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
Expand Down Expand Up @@ -927,3 +931,27 @@ object SendClass : StreamEventsStreamHandler() {
handler.postDelayed(r, 10)
}
}

class SendConsistentNumbers(private val numberToSend: Long) :
StreamConsistentNumbersStreamHandler() {
private val handler = Handler(Looper.getMainLooper())

override fun onListen(p0: Any?, sink: PigeonEventSink<Long>) {
var count: Int = 0
val r: Runnable =
object : Runnable {
override fun run() {
if (count >= 10) {
sink.endOfStream()
} else {
handler.post {
sink.success(numberToSend)
count++
}
handler.postDelayed(this, 10)
}
}
}
handler.postDelayed(r, 10)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -574,3 +574,21 @@ class StreamEventsStreamHandler: PigeonEventChannelWrapper<PlatformEvent> {
channel.setStreamHandler(internalStreamHandler)
}
}

class StreamConsistentNumbersStreamHandler: PigeonEventChannelWrapper<Int64> {
static func register(
with messenger: FlutterBinaryMessenger,
instanceName: String = "",
streamHandler: StreamConsistentNumbersStreamHandler
) {
var channelName =
"dev.flutter.pigeon.pigeon_integration_tests.EventChannelMethods.streamConsistentNumbers"
if !instanceName.isEmpty {
channelName += ".\(instanceName)"
}
let internalStreamHandler = PigeonStreamHandler<Int64>(wrapper: streamHandler)
let channel = FlutterEventChannel(
name: channelName, binaryMessenger: messenger, codec: eventChannelTestsPigeonMethodCodec)
channel.setStreamHandler(internalStreamHandler)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi {

StreamIntsStreamHandler.register(with: binaryMessenger, streamHandler: SendInts())
StreamEventsStreamHandler.register(with: binaryMessenger, streamHandler: SendEvents())
StreamConsistentNumbersStreamHandler.register(
with: binaryMessenger, instanceName: "1",
streamHandler: SendConsistentNumbers(numberToSend: 1))
StreamConsistentNumbersStreamHandler.register(
with: binaryMessenger, instanceName: "2",
streamHandler: SendConsistentNumbers(numberToSend: 2))
proxyApiRegistrar = ProxyApiTestsPigeonProxyApiRegistrar(
binaryMessenger: binaryMessenger, apiDelegate: ProxyApiDelegate())
proxyApiRegistrar!.setUp()
Expand Down Expand Up @@ -1272,6 +1278,33 @@ class SendEvents: StreamEventsStreamHandler {
}
}

class SendConsistentNumbers: StreamConsistentNumbersStreamHandler {
let numberToSend: Int64
init(numberToSend: Int64) {
self.numberToSend = numberToSend
}
var timerActive = false
var timer: Timer?

override func onListen(withArguments arguments: Any?, sink: PigeonEventSink<Int64>) {
let numberThatWillBeSent: Int64 = numberToSend
var count: Int64 = 0
if !timerActive {
timerActive = true
timer = Timer.scheduledTimer(withTimeInterval: 0.01, repeats: true) { _ in
DispatchQueue.main.async {
sink.success(numberThatWillBeSent)
count += 1
if count >= 10 {
sink.endOfStream()
self.timer?.invalidate()
}
}
}
}
}
}

class ProxyApiDelegate: ProxyApiTestsPigeonProxyApiDelegate {
func pigeonApiProxyApiTestClass(_ registrar: ProxyApiTestsPigeonProxyApiRegistrar)
-> PigeonApiProxyApiTestClass
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -574,3 +574,21 @@ class StreamEventsStreamHandler: PigeonEventChannelWrapper<PlatformEvent> {
channel.setStreamHandler(internalStreamHandler)
}
}

class StreamConsistentNumbersStreamHandler: PigeonEventChannelWrapper<Int64> {
static func register(
with messenger: FlutterBinaryMessenger,
instanceName: String = "",
streamHandler: StreamConsistentNumbersStreamHandler
) {
var channelName =
"dev.flutter.pigeon.pigeon_integration_tests.EventChannelMethods.streamConsistentNumbers"
if !instanceName.isEmpty {
channelName += ".\(instanceName)"
}
let internalStreamHandler = PigeonStreamHandler<Int64>(wrapper: streamHandler)
let channel = FlutterEventChannel(
name: channelName, binaryMessenger: messenger, codec: eventChannelTestsPigeonMethodCodec)
channel.setStreamHandler(internalStreamHandler)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi {
binaryMessenger: binaryMessenger, messageChannelSuffix: "suffixOne")
flutterSmallApiTwo = FlutterSmallApi(
binaryMessenger: binaryMessenger, messageChannelSuffix: "suffixTwo")
StreamConsistentNumbersStreamHandler.register(
with: binaryMessenger, instanceName: "1",
streamHandler: SendConsistentNumbers(numberToSend: 1))
StreamConsistentNumbersStreamHandler.register(
with: binaryMessenger, instanceName: "2",
streamHandler: SendConsistentNumbers(numberToSend: 2))
proxyApiRegistrar = ProxyApiTestsPigeonProxyApiRegistrar(
binaryMessenger: binaryMessenger, apiDelegate: ProxyApiDelegate())
proxyApiRegistrar!.setUp()
Expand Down Expand Up @@ -1270,6 +1276,33 @@ class SendEvents: StreamEventsStreamHandler {
}
}

class SendConsistentNumbers: StreamConsistentNumbersStreamHandler {
let numberToSend: Int64
init(numberToSend: Int64) {
self.numberToSend = numberToSend
}
var timerActive = false
var timer: Timer?

override func onListen(withArguments arguments: Any?, sink: PigeonEventSink<Int64>) {
let numberThatWillBeSent: Int64 = numberToSend
var count: Int64 = 0
if !timerActive {
timerActive = true
timer = Timer.scheduledTimer(withTimeInterval: 0.01, repeats: true) { _ in
DispatchQueue.main.async {
sink.success(numberThatWillBeSent)
count += 1
if count >= 10 {
sink.endOfStream()
self.timer?.invalidate()
}
}
}
}
}
}

class ProxyApiDelegate: ProxyApiTestsPigeonProxyApiDelegate {
func pigeonApiProxyApiTestClass(_ registrar: ProxyApiTestsPigeonProxyApiRegistrar)
-> PigeonApiProxyApiTestClass
Expand Down
2 changes: 1 addition & 1 deletion packages/pigeon/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: pigeon
description: Code generator tool to make communication between Flutter and the host platform type-safe and easier.
repository: https://github.com/flutter/packages/tree/main/packages/pigeon
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+pigeon%22
version: 22.7.3 # This must match the version in lib/generator_tools.dart
version: 22.7.4 # This must match the version in lib/generator_tools.dart

environment:
sdk: ^3.4.0
Expand Down

0 comments on commit 894640f

Please sign in to comment.