Line data Source code
1 : import 'dart:async'; 2 : import 'dart:ui' as ui; 3 : 4 : import 'package:combine/src/id_generator.dart/id_generator.dart'; 5 : import 'package:combine/src/isolate_events.dart'; 6 : import 'package:combine/src/isolate_messenger/internal_isolate_messenger/internal_isolate_messenger.dart'; 7 : import 'package:flutter/services.dart'; 8 : 9 : /// This class receives messages from [MethodChannel] and sends them to the 10 : /// UI Isolate. 11 : class IsolatedMethodChannelMiddleware extends BinaryMessenger { 12 : /// Creates new middleware and sets [instance]. 13 2 : IsolatedMethodChannelMiddleware(this._isolateMessenger) 14 2 : : _generateId = IdGenerator(); 15 : 16 : /// Last created and [initialize]d middleware. 17 : static IsolatedMethodChannelMiddleware? instance; 18 : 19 : final InternalIsolateMessenger _isolateMessenger; 20 : late BinaryMessenger _binaryMessenger; 21 : final IdGenerator _generateId; 22 : final _platformResponsesCompleter = <int, Completer<ByteData?>>{}; 23 : 24 : /// Starts listening for [MethodChannelEvent]s from UI Isolate and sets middleware for [MethodChannel]. 25 2 : void initialize() { 26 : instance = this; 27 4 : _isolateMessenger.messagesStream 28 6 : .where((event) => event is IsolateEvent) 29 2 : .cast<IsolateEvent>() 30 4 : .listen(_listenForMethodChannelEvents); 31 : } 32 : 33 2 : void setBinaryMessage(BinaryMessenger binaryMessenger) { 34 2 : _binaryMessenger = binaryMessenger; 35 : } 36 : 37 1 : void _listenForMethodChannelEvents(IsolateEvent event) { 38 1 : switch (event.runtimeType) { 39 1 : case PlatformChannelResponseEvent: 40 : final responseEvent = event as PlatformChannelResponseEvent; 41 3 : _platformChannelResponse(responseEvent.id, responseEvent.data); 42 : break; 43 1 : case InvokeMethodChannelEvent: 44 : final invokeEvent = event as InvokeMethodChannelEvent; 45 1 : _handlePlatformMessage( 46 1 : invokeEvent.channel, 47 1 : invokeEvent.id, 48 1 : invokeEvent.data, 49 : ); 50 : break; 51 : } 52 : } 53 : 54 : /// Handle platform messages and send them to it's [MessageChannel]. 55 1 : void _handlePlatformMessage(String channel, int id, ByteData? message) { 56 2 : handlePlatformMessage(channel, message, (data) { 57 3 : _isolateMessenger.send(MethodChannelResponseEvent(data, id)); 58 : }); 59 : } 60 : 61 : /// Sends response from platform channel to it's message handler. 62 1 : void _platformChannelResponse(int id, ByteData? response) { 63 2 : final completer = _platformResponsesCompleter.remove(id); 64 : assert( 65 1 : completer != null, 66 : "Failed to send response from platform channel " 67 : "to it's message handler.", 68 : ); 69 1 : completer?.complete(response); 70 : } 71 : 72 1 : @override 73 : Future<void> handlePlatformMessage( 74 : String channel, 75 : ByteData? data, 76 : ui.PlatformMessageResponseCallback? callback, 77 : ) async { 78 2 : await _binaryMessenger.handlePlatformMessage(channel, data, callback); 79 : } 80 : 81 1 : @override 82 : Future<ByteData?>? send(String channel, ByteData? message) { 83 1 : final completer = Completer<ByteData?>(); 84 2 : final id = _generateId(); 85 2 : _platformResponsesCompleter[id] = completer; 86 3 : _isolateMessenger.send(InvokePlatformChannelEvent(message, channel, id)); 87 1 : return completer.future; 88 : } 89 : 90 2 : @override 91 : void setMessageHandler(String channel, MessageHandler? handler) { 92 4 : _binaryMessenger.setMessageHandler(channel, handler); 93 : } 94 : } 95 : 96 : typedef PlatformMessageHandler = void Function( 97 : String channel, 98 : ByteData? message, 99 : ui.PlatformMessageResponseCallback? callback, 100 : ); 101 : 102 : typedef PlatformResponseHandler = Future<ByteData?>? Function( 103 : String channel, 104 : ByteData? message, 105 : );