Kate Lovett 9d96df2364
Modernize framework lints (#179089)
WIP

Commits separated as follows:
- Update lints in analysis_options files
- Run `dart fix --apply`
- Clean up leftover analysis issues 
- Run `dart format .` in the right places.

Local analysis and testing passes. Checking CI now.

Part of https://github.com/flutter/flutter/issues/178827
- Adoption of flutter_lints in examples/api coming in a separate change
(cc @loic-sharma)

## Pre-launch Checklist

- [ ] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [ ] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [ ] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [ ] I signed the [CLA].
- [ ] I listed at least one issue that this PR fixes in the description
above.
- [ ] I updated/added relevant documentation (doc comments with `///`).
- [ ] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [ ] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [ ] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

**Note**: The Flutter team is currently trialing the use of [Gemini Code
Assist for
GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).
Comments from the `gemini-code-assist` bot should not be taken as
authoritative feedback from the Flutter team. If you find its comments
useful you can update your code accordingly, but if you are unsure or
disagree with the feedback, please feel free to wait for a Flutter team
member's review for guidance on which automated comments should be
addressed.

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
2025-11-26 01:10:39 +00:00

229 lines
7.3 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 'dart:ui' as ui;
import 'dart:ui_web' as ui_web;
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
// Examples can assume:
// import 'package:flutter_web_plugins/flutter_web_plugins.dart';
// import 'package:flutter/services.dart';
// import 'dart:ui_web' as ui_web;
// void handleFrameworkMessage(String name, ByteData? data, PlatformMessageResponseCallback? callback) { }
/// A registrar for Flutter plugins implemented in Dart.
///
/// Plugins for the web platform are implemented in Dart and are
/// registered with this class by code generated by the `flutter` tool
/// when compiling the application.
///
/// This class implements [BinaryMessenger] to route messages from the
/// framework to registered plugins.
///
/// Use this [BinaryMessenger] when creating platform channels in order for
/// them to receive messages from the platform side. For example:
///
/// ```dart
/// class MyPlugin {
/// static void registerWith(Registrar registrar) {
/// final MethodChannel channel = MethodChannel(
/// 'com.my_plugin/my_plugin',
/// const StandardMethodCodec(),
/// registrar, // the registrar is used as the BinaryMessenger
/// );
/// final MyPlugin instance = MyPlugin();
/// channel.setMethodCallHandler(instance.handleMethodCall);
/// }
///
/// Future<dynamic> handleMethodCall(MethodCall call) async {
/// // ...
/// }
///
/// // ...
/// }
/// ```
class Registrar extends BinaryMessenger {
/// Creates a [Registrar].
///
/// The argument is ignored. To create a test [Registrar] with custom behavior,
/// subclass the [Registrar] class and override methods as appropriate.
Registrar([
@Deprecated(
'This argument is ignored. '
'This feature was deprecated after v1.24.0-7.0.pre.',
)
BinaryMessenger? binaryMessenger,
]);
/// Registers the registrar's message handler
/// ([handlePlatformMessage]) with the engine, so that plugin
/// messages are correctly dispatched to the relevant registered
/// plugin.
///
/// Only one handler can be registered at a time. Calling this
/// method a second time silently unregisters any
/// previously-registered handler and replaces it with the handler
/// from this object.
///
/// This method uses a function called `setPluginHandler` in
/// the [dart:ui_web] library. That function is only available when
/// compiling for the web.
void registerMessageHandler() {
ui_web.setPluginHandler(handleFrameworkMessage);
}
/// Receives a platform message from the framework.
///
/// This method has been replaced with the more clearly-named [handleFrameworkMessage].
@Deprecated(
'Use handleFrameworkMessage instead. '
'This feature was deprecated after v1.24.0-7.0.pre.',
)
@override
Future<void> handlePlatformMessage(
String channel,
ByteData? data,
ui.PlatformMessageResponseCallback? callback,
) => handleFrameworkMessage(channel, data, callback);
/// Message handler for web plugins.
///
/// This method is called when handling messages from the framework.
///
/// If a handler has been registered for the given `channel`, it is
/// invoked, and the value it returns is passed to `callback` (if that
/// is non-null). Then, the method's future is completed.
///
/// If no handler has been registered for that channel, then the
/// callback (if any) is invoked with null, then the method's future
/// is completed.
///
/// Messages are not buffered (unlike platform messages headed to
/// the framework, which are managed by [ChannelBuffers]).
///
/// This method is registered as the message handler by code
/// autogenerated by the `flutter` tool when the application is
/// compiled, if any web plugins are used. The code in question is
/// the following:
///
/// ```dart
/// ui_web.setPluginHandler(handleFrameworkMessage);
/// ```
Future<void> handleFrameworkMessage(
String channel,
ByteData? data,
ui.PlatformMessageResponseCallback? callback,
) async {
ByteData? response;
try {
final MessageHandler? handler = _handlers[channel];
if (handler != null) {
response = await handler(data);
}
} catch (exception, stack) {
FlutterError.reportError(
FlutterErrorDetails(
exception: exception,
stack: stack,
library: 'flutter web plugins',
context: ErrorDescription('during a framework-to-plugin message'),
),
);
} finally {
if (callback != null) {
callback(response);
}
}
}
/// Returns `this`.
@Deprecated(
'This property is redundant. It returns the object on which it is called. '
'This feature was deprecated after v1.24.0-7.0.pre.',
)
BinaryMessenger get messenger => this;
final Map<String, MessageHandler> _handlers = <String, MessageHandler>{};
/// Sends a platform message from the platform side back to the framework.
@override
Future<ByteData?> send(String channel, ByteData? message) {
final completer = Completer<ByteData?>();
ui.channelBuffers.push(channel, message, (ByteData? reply) {
try {
completer.complete(reply);
} catch (exception, stack) {
FlutterError.reportError(
FlutterErrorDetails(
exception: exception,
stack: stack,
library: 'flutter web plugins',
context: ErrorDescription('during a plugin-to-framework message'),
),
);
}
});
return completer.future;
}
@override
void setMessageHandler(String channel, MessageHandler? handler) {
if (handler == null) {
_handlers.remove(channel);
} else {
_handlers[channel] = handler;
}
}
}
/// This class was previously separate from [Registrar] but was merged into it
/// as part of a simplification of the web plugins API.
@Deprecated(
'Use Registrar instead. '
'This feature was deprecated after v1.26.0-18.0.pre.',
)
class PluginRegistry extends Registrar {
/// Creates a [Registrar].
///
/// The argument is ignored.
@Deprecated(
'Use Registrar instead. '
'This feature was deprecated after v1.26.0-18.0.pre.',
)
PluginRegistry([
@Deprecated(
'This argument is ignored. '
'This feature was deprecated after v1.26.0-18.0.pre.',
)
BinaryMessenger? binaryMessenger,
]) : super();
/// Returns `this`. The argument is ignored.
@Deprecated(
'This method is redundant. It returns the object on which it is called. '
'This feature was deprecated after v1.26.0-18.0.pre.',
)
Registrar registrarFor(Type key) => this;
}
/// The default plugin registrar for the web.
final Registrar webPluginRegistrar = PluginRegistry();
/// A deprecated alias for [webPluginRegistrar].
@Deprecated(
'Use webPluginRegistrar instead. '
'This feature was deprecated after v1.24.0-7.0.pre.',
)
PluginRegistry get webPluginRegistry => webPluginRegistrar as PluginRegistry;
/// A deprecated alias for [webPluginRegistrar].
@Deprecated(
'Use webPluginRegistrar instead. '
'This feature was deprecated after v1.24.0-7.0.pre.',
)
BinaryMessenger get pluginBinaryMessenger => webPluginRegistrar;