
* Update project.pbxproj files to say Flutter rather than Chromium Also, the templates now have an empty organization so that we don't cause people to give their apps a Flutter copyright. * Update the copyright notice checker to require a standard notice on all files * Update copyrights on Dart files. (This was a mechanical commit.) * Fix weird license headers on Dart files that deviate from our conventions; relicense Shrine. Some were already marked "The Flutter Authors", not clear why. Their dates have been normalized. Some were missing the blank line after the license. Some were randomly different in trivial ways for no apparent reason (e.g. missing the trailing period). * Clean up the copyrights in non-Dart files. (Manual edits.) Also, make sure templates don't have copyrights. * Fix some more ORGANIZATIONNAMEs
111 lines
3.4 KiB
Dart
111 lines
3.4 KiB
Dart
// Copyright 2014 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.
|
|
|
|
import 'dart:async';
|
|
|
|
import 'package:flutter/services.dart';
|
|
|
|
import 'plugin_registry.dart';
|
|
|
|
/// A named channel for sending events to the framework-side using streams.
|
|
///
|
|
/// This is the platform-side equivalent of [EventChannel]. Whereas
|
|
/// [EventChannel] receives a stream of events from platform plugins, this
|
|
/// channel sends a stream of events to the handler listening on the
|
|
/// framework-side.
|
|
///
|
|
/// The channel [name] must not be null. If no [codec] is provided, then
|
|
/// [StandardMethodCodec] is used. If no [binaryMessenger] is provided, then
|
|
/// [pluginBinaryMessenger], which sends messages to the framework-side,
|
|
/// is used.
|
|
class PluginEventChannel<T> {
|
|
/// Creates a new plugin event channel.
|
|
const PluginEventChannel(
|
|
this.name, [
|
|
this.codec = const StandardMethodCodec(),
|
|
BinaryMessenger binaryMessenger,
|
|
]) : assert(name != null),
|
|
assert(codec != null),
|
|
_binaryMessenger = binaryMessenger;
|
|
|
|
/// The logical channel on which communication happens.
|
|
///
|
|
/// This must not be null.
|
|
final String name;
|
|
|
|
/// The message codec used by this channel.
|
|
///
|
|
/// This must not be null. This defaults to [StandardMethodCodec].
|
|
final MethodCodec codec;
|
|
|
|
/// The messenger used by this channel to send platform messages.
|
|
///
|
|
/// This must not be null. If not provided, defaults to
|
|
/// [pluginBinaryMessenger], which sends messages from the platform-side
|
|
/// to the framework-side.
|
|
BinaryMessenger get binaryMessenger =>
|
|
_binaryMessenger ?? pluginBinaryMessenger;
|
|
final BinaryMessenger _binaryMessenger;
|
|
|
|
/// Set the stream controller for this event channel.
|
|
set controller(StreamController<T> controller) {
|
|
final _EventChannelHandler<T> handler = _EventChannelHandler<T>(
|
|
name,
|
|
codec,
|
|
controller,
|
|
binaryMessenger,
|
|
);
|
|
binaryMessenger.setMessageHandler(
|
|
name, controller == null ? null : handler.handle);
|
|
}
|
|
}
|
|
|
|
class _EventChannelHandler<T> {
|
|
_EventChannelHandler(this.name, this.codec, this.controller, this.messenger);
|
|
|
|
final String name;
|
|
final MethodCodec codec;
|
|
final StreamController<T> controller;
|
|
final BinaryMessenger messenger;
|
|
|
|
StreamSubscription<T> subscription;
|
|
|
|
Future<ByteData> handle(ByteData message) {
|
|
final MethodCall call = codec.decodeMethodCall(message);
|
|
switch (call.method) {
|
|
case 'listen':
|
|
return _listen();
|
|
case 'cancel':
|
|
return _cancel();
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// TODO(hterkelsen): Support arguments.
|
|
Future<ByteData> _listen() async {
|
|
if (subscription != null) {
|
|
await subscription.cancel();
|
|
}
|
|
subscription = controller.stream.listen((dynamic event) {
|
|
messenger.send(name, codec.encodeSuccessEnvelope(event));
|
|
}, onError: (dynamic error) {
|
|
messenger.send(name,
|
|
codec.encodeErrorEnvelope(code: 'error', message: error.toString()));
|
|
});
|
|
|
|
return codec.encodeSuccessEnvelope(null);
|
|
}
|
|
|
|
// TODO(hterkelsen): Support arguments.
|
|
Future<ByteData> _cancel() async {
|
|
if (subscription == null) {
|
|
return codec.encodeErrorEnvelope(
|
|
code: 'error', message: 'No active stream to cancel.');
|
|
}
|
|
await subscription.cancel();
|
|
subscription = null;
|
|
return codec.encodeSuccessEnvelope(null);
|
|
}
|
|
}
|