## Description This removes all of the comments that are of the form "so-and-so must not be null" or "so-and-so must be non-null" from the cases where those values are defines as non-nullable values. This PR removes them from the library in the repo that don't have anything to do with the framework. This was done by hand, since it really didn't lend itself to scripting, so it needs to be more than just spot-checked, I think. I was careful to leave any comment that referred to parameters that were nullable, but I may have missed some. In addition to being no longer relevant after null safety has been made the default, these comments were largely fragile, in that it was easy for them to get out of date, and not be accurate anymore anyhow. This did create a number of constructor comments which basically say "Creates a [Foo].", but I don't really know how to avoid that in a large scale change, since there's not much you can really say in a lot of cases. I think we might consider some leniency for constructors to the "Comment must be meaningful" style guidance (which we de facto have already, since there are a bunch of these). ## Related PRs - https://github.com/flutter/flutter/pull/134984 - https://github.com/flutter/flutter/pull/134991 - https://github.com/flutter/flutter/pull/134992 - https://github.com/flutter/flutter/pull/134993 ## Tests - Documentation only change.
150 lines
4.9 KiB
Dart
150 lines
4.9 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.
|
|
///
|
|
/// 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.
|
|
///
|
|
/// Channels created using this class implement two methods for
|
|
/// subscribing to the event stream. The methods use the encoding of
|
|
/// the specified [codec].
|
|
///
|
|
/// The first method is `listen`. When called, it begins forwarding
|
|
/// messages to the framework side when they are added to the
|
|
/// `controller`. This triggers the [StreamController.onListen] callback
|
|
/// on the `controller`.
|
|
///
|
|
/// The other method is `cancel`. When called, it stops forwarding
|
|
/// events to the framework. This triggers the [StreamController.onCancel]
|
|
/// callback on the `controller`.
|
|
///
|
|
/// Events added to the `controller` when the framework is not
|
|
/// subscribed are silently discarded.
|
|
class PluginEventChannel<T> {
|
|
/// Creates a new plugin event channel.
|
|
const PluginEventChannel(
|
|
this.name, [
|
|
this.codec = const StandardMethodCodec(),
|
|
this.binaryMessenger,
|
|
]);
|
|
|
|
/// The logical channel on which communication happens.
|
|
final String name;
|
|
|
|
/// The message codec used by this channel.
|
|
///
|
|
/// Defaults to [StandardMethodCodec].
|
|
final MethodCodec codec;
|
|
|
|
/// The messenger used by this channel to send platform messages.
|
|
///
|
|
/// When this is null, the [pluginBinaryMessenger] is used instead,
|
|
/// which sends messages from the platform-side to the
|
|
/// framework-side.
|
|
final BinaryMessenger? binaryMessenger;
|
|
|
|
/// Use [setController] instead.
|
|
///
|
|
/// This setter is deprecated because it has no corresponding getter,
|
|
/// and providing a getter would require making this class non-const.
|
|
@Deprecated(
|
|
'Replace calls to the "controller" setter with calls to the "setController" method. '
|
|
'This feature was deprecated after v1.23.0-7.0.pre.'
|
|
)
|
|
set controller(StreamController<T> controller) { // ignore: avoid_setters_without_getters
|
|
setController(controller);
|
|
}
|
|
|
|
/// Changes the stream controller for this event channel.
|
|
///
|
|
/// Setting the controller to null disconnects from the channel (setting
|
|
/// the message handler on the [binaryMessenger] to null).
|
|
void setController(StreamController<T>? controller) {
|
|
final BinaryMessenger messenger = binaryMessenger ?? pluginBinaryMessenger;
|
|
if (controller == null) {
|
|
messenger.setMessageHandler(name, null);
|
|
} else {
|
|
// The handler object is kept alive via its handle() method
|
|
// keeping a reference to itself. Ideally we would keep a
|
|
// reference to it so that there was a clear ownership model,
|
|
// but that would require making this class non-const. Having
|
|
// this class be const is convenient since it allows references
|
|
// to be obtained by using the constructor rather than having
|
|
// to literally pass references around.
|
|
final _EventChannelHandler<T> handler = _EventChannelHandler<T>(
|
|
name,
|
|
codec,
|
|
controller,
|
|
messenger,
|
|
);
|
|
messenger.setMessageHandler(name, 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':
|
|
assert(call.arguments == null);
|
|
return _listen();
|
|
case 'cancel':
|
|
assert(call.arguments == null);
|
|
return _cancel();
|
|
}
|
|
return null;
|
|
}
|
|
|
|
Future<ByteData> _listen() async {
|
|
// Cancel any existing subscription.
|
|
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'));
|
|
});
|
|
return codec.encodeSuccessEnvelope(null);
|
|
}
|
|
|
|
Future<ByteData> _cancel() async {
|
|
if (subscription == null) {
|
|
return codec.encodeErrorEnvelope(
|
|
code: 'error',
|
|
message: 'No active subscription to cancel.',
|
|
);
|
|
}
|
|
await subscription!.cancel();
|
|
subscription = null;
|
|
return codec.encodeSuccessEnvelope(null);
|
|
}
|
|
}
|