Line data Source code
1 : import 'dart:async'; 2 : import 'dart:ui' as ui; 3 : 4 : import 'package:combine/src/isolate_events.dart'; 5 : import 'package:combine/src/isolate_messenger/internal_isolate_messenger/internal_isolate_messenger.dart'; 6 : import 'package:flutter/services.dart'; 7 : import 'package:uuid/uuid.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 5 : IsolatedMethodChannelMiddleware(this._isolateMessenger) 14 5 : : _generateId = const Uuid().v4; 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 = <String, Completer<ByteData?>>{}; 23 : 24 : /// Starts listening for [MethodChannelEvent]s from UI Isolate and sets middleware for [MethodChannel]. 25 5 : void initialize() { 26 : instance = this; 27 10 : _isolateMessenger.messagesStream 28 15 : .where((event) => event is IsolateEvent) 29 5 : .cast<IsolateEvent>() 30 10 : .listen(_listenForMethodChannelEvents); 31 : } 32 : 33 5 : void setBinaryMessage(BinaryMessenger binaryMessenger) { 34 5 : _binaryMessenger = binaryMessenger; 35 : } 36 : 37 5 : void _listenForMethodChannelEvents(IsolateEvent event) { 38 5 : switch (event.runtimeType) { 39 5 : case PlatformChannelResponseEvent: 40 : final responseEvent = event as PlatformChannelResponseEvent; 41 15 : _platformChannelResponse(responseEvent.id, responseEvent.data); 42 : break; 43 5 : case InvokeMethodChannelEvent: 44 : final invokeEvent = event as InvokeMethodChannelEvent; 45 5 : _handlePlatformMessage( 46 5 : invokeEvent.channel, 47 5 : invokeEvent.id, 48 5 : invokeEvent.data, 49 : ); 50 : break; 51 : } 52 : } 53 : 54 : /// Handle platform messages and send them to it's [MessageChannel]. 55 5 : void _handlePlatformMessage(String channel, String id, ByteData? message) { 56 10 : handlePlatformMessage(channel, message, (data) { 57 15 : _isolateMessenger.send(MethodChannelResponseEvent(data, id)); 58 : }); 59 : } 60 : 61 : /// Sends response from platform channel to it's message handler. 62 5 : void _platformChannelResponse(String id, ByteData? response) { 63 10 : final completer = _platformResponsesCompleter.remove(id); 64 : assert( 65 5 : completer != null, 66 : "Failed to send response from platform channel " 67 : "to it's message handler.", 68 : ); 69 5 : completer?.complete(response); 70 : } 71 : 72 : @override 73 5 : Future<void> handlePlatformMessage( 74 : String channel, 75 : ByteData? data, 76 : ui.PlatformMessageResponseCallback? callback, 77 : ) async { 78 15 : await _binaryMessenger.handlePlatformMessage(channel, data, callback); 79 : } 80 : 81 5 : @override 82 : Future<ByteData?>? send(String channel, ByteData? message) { 83 5 : final completer = Completer<ByteData?>(); 84 10 : final id = _generateId(); 85 10 : _platformResponsesCompleter[id] = completer; 86 15 : _isolateMessenger.send(InvokePlatformChannelEvent(message, channel, id)); 87 5 : return completer.future; 88 : } 89 : 90 5 : @override 91 : void setMessageHandler(String channel, MessageHandler? handler) { 92 10 : _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 : ); 106 : 107 : typedef IdGenerator = String Function();