[extension_google_sign_in_as_googleapis_auth] Move from flutter/plugins. (#301)
diff --git a/.cirrus.yml b/.cirrus.yml
index 91a71f1..d88484c 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -1,5 +1,6 @@
+use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true'
+
task:
- use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true' && $CIRRUS_PR == ''
container:
dockerfile: .ci/Dockerfile
cpu: 4
@@ -7,8 +8,6 @@
upgrade_script:
- flutter channel master
- flutter upgrade
- # TODO(goderbauer): Remove next two lines when https://github.com/flutter/flutter/issues/74772 is resolved.
- - rm -rf /home/cirrus/sdks/flutter/bin/cache
- flutter doctor
- git fetch origin master
activate_script: pub global activate flutter_plugin_tools
@@ -46,41 +45,34 @@
- dart testing/web_benchmarks_test.dart
task:
- use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true'
name: build-ipas
osx_instance:
- image: high-sierra-xcode-9.4.1
+ image: big-sur-xcode-12.4
env:
PATH: $PATH:/usr/local/bin
matrix:
BUILD_SHARDING: "--shardIndex 0 --shardCount 2"
BUILD_SHARDING: "--shardIndex 1 --shardCount 2"
setup_script:
- - pod repo update
- - git clone https://github.com/flutter/flutter.git
- - git fetch origin master
- - export PATH=`pwd`/flutter/bin:`pwd`/flutter/bin/cache/dart-sdk/bin:$PATH
+ - flutter channel master
+ - flutter upgrade
- flutter doctor
+ - git fetch origin master
- pub global activate flutter_plugin_tools
build_script:
- - export PATH=`pwd`/flutter/bin:`pwd`/flutter/bin/cache/dart-sdk/bin:$PATH
- ./script/incremental_build.sh build-examples --ipa
task:
- use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true'
name: local_tests
osx_instance:
- image: catalina-flutter
+ image: big-sur-xcode-12.4
env:
PATH: $PATH:/usr/local/bin
matrix:
CHANNEL: "master"
CHANNEL: "stable"
setup_script:
- - pod repo update
- - git clone https://github.com/flutter/flutter.git
- git fetch origin master
- - export PATH=`pwd`/flutter/bin:`pwd`/flutter/bin/cache/dart-sdk/bin:$PATH
- pub global activate flutter_plugin_tools
- brew install clang-format
upgrade_script:
diff --git a/README.md b/README.md
index 36b2f0c..8430ac8 100644
--- a/README.md
+++ b/README.md
@@ -38,4 +38,5 @@
| [multicast_dns](./packages/multicast_dns/) | [![pub package](https://img.shields.io/pub/v/multicast_dns.svg)](https://pub.dev/packages/multicast_dns) |
| [palette_generator](./packages/palette_generator/) | [![pub package](https://img.shields.io/pub/v/palette_generator.svg)](https://pub.dartlang.org/packages/palette_generator) |
| [pigeon](./packages/pigeon/) | [![pub package](https://img.shields.io/pub/v/pigeon.svg)](https://pub.dev/packages/pigeon) |
+| [pointer_interceptor](./packages/pointer_interceptor/) | [![pub package](https://img.shields.io/pub/v/pointer_interceptor.svg)](https://pub.dev/packages/pointer_interceptor) |
| [xdg_directories](./packages/xdg_directories/) | [![pub package](https://img.shields.io/pub/v/xdg_directories.svg)](https://pub.dev/packages/xdg_directories) |
diff --git a/packages/animations/CHANGELOG.md b/packages/animations/CHANGELOG.md
index 70ec9b4..0ab0f79 100644
--- a/packages/animations/CHANGELOG.md
+++ b/packages/animations/CHANGELOG.md
@@ -1,20 +1,17 @@
-# Changelog
-
-All notable changes to this project will be documented in this file.
-
-## [2.0.0-nullsafety.0] - November 16, 2020
+## 2.0.0
* Migrates to null safety.
+* Add `routeSettings` and `filter` option to `showModal`.
-## [1.1.2] - July 28, 2020
+## 1.1.2
* Fixes for upcoming changes to the flutter framework.
-## [1.1.1] - June 19, 2020
+## 1.1.1
* Hide implementation of `DualTransitionBuilder` as the widget has been implemented in the Flutter framework.
-## [1.1.0] - June 2, 2020
+## 1.1.0
* Introduce usage of `DualTransitionBuilder` for all transition widgets, preventing ongoing animations at the start of the transition animation from resetting at the end of the transition animations.
* Fix `FadeScaleTransition` example's `FloatingActionButton` being accessible
@@ -28,12 +25,12 @@
* Fixes a bug with OpenContainer where a crash occurs when the container is dismissed after the container widget itself is removed.
-## [1.0.0+5] - February 21, 2020
+## 1.0.0+5
* Fix override analyzer ignore placement.
-## [1.0.0+4] - February 21, 2020
+## 1.0.0+4
* Fix a typo in the changelog dates
* Revert use of modern Material text style nomenclature in the example app
@@ -43,21 +40,21 @@
https://github.com/flutter/flutter/pull/48274.
-## [1.0.0+3] - February 18, 2020
+## 1.0.0+3
* Update README.md to better describe Material motion
-## [1.0.0+2] - February 18, 2020
+## 1.0.0+2
* Fixes to pubspec.yaml
-## [1.0.0+1] - February 18, 2020
+## 1.0.0+1
* Fixes to pubspec.yaml
-## [1.0.0] - February 18, 2020
+## 1.0.0
* Initial release
diff --git a/packages/animations/example/pubspec.yaml b/packages/animations/example/pubspec.yaml
index 68a79d1..ecee1e8 100644
--- a/packages/animations/example/pubspec.yaml
+++ b/packages/animations/example/pubspec.yaml
@@ -6,12 +6,12 @@
version: 0.0.1
environment:
- sdk: ">=2.12.0-0 <3.0.0"
+ sdk: ">=2.12.0-259.9.beta <3.0.0"
dependencies:
animations:
path: ../../animations
- cupertino_icons: ^0.1.2
+ cupertino_icons: ^1.0.2
flutter:
sdk: flutter
diff --git a/packages/animations/lib/src/modal.dart b/packages/animations/lib/src/modal.dart
index 120d51f..65b6f60 100644
--- a/packages/animations/lib/src/modal.dart
+++ b/packages/animations/lib/src/modal.dart
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+import 'dart:ui' as ui;
+
import 'package:flutter/material.dart';
import 'fade_scale_transition.dart';
@@ -51,6 +53,8 @@
ModalConfiguration configuration = const FadeScaleTransitionConfiguration(),
bool useRootNavigator = true,
required WidgetBuilder builder,
+ RouteSettings? routeSettings,
+ ui.ImageFilter? filter,
}) {
String? barrierLabel = configuration.barrierLabel;
// Avoid looking up [MaterialLocalizations.of(context).modalBarrierDismissLabel]
@@ -68,6 +72,8 @@
transitionDuration: configuration.transitionDuration,
reverseTransitionDuration: configuration.reverseTransitionDuration,
builder: builder,
+ routeSettings: routeSettings,
+ filter: filter,
),
);
}
@@ -91,8 +97,11 @@
required this.reverseTransitionDuration,
required _ModalTransitionBuilder transitionBuilder,
required this.builder,
- }) : assert(!barrierDismissible || barrierLabel != null),
- _transitionBuilder = transitionBuilder;
+ RouteSettings? routeSettings,
+ ui.ImageFilter? filter,
+ }) : assert(!barrierDismissible || barrierLabel != null),
+ _transitionBuilder = transitionBuilder,
+ super(filter: filter, settings: routeSettings);
@override
final Color? barrierColor;
diff --git a/packages/animations/pubspec.yaml b/packages/animations/pubspec.yaml
index 8417e19..81150b1 100644
--- a/packages/animations/pubspec.yaml
+++ b/packages/animations/pubspec.yaml
@@ -1,10 +1,10 @@
name: animations
description: Fancy pre-built animations that can easily be integrated into any Flutter application.
-version: 2.0.0-nullsafety.0
+version: 2.0.0
homepage: https://github.com/flutter/packages/tree/master/packages/animations
environment:
- sdk: '>=2.12.0-0 <3.0.0'
+ sdk: '>=2.12.0-259.9.beta <3.0.0'
dependencies:
flutter:
@@ -13,4 +13,4 @@
dev_dependencies:
flutter_test:
sdk: flutter
- vector_math: ">=2.1.0-nullsafety.5 <3.0.0"
+ vector_math: ^2.1.0
diff --git a/packages/animations/test/modal_test.dart b/packages/animations/test/modal_test.dart
index fdaf10c..7d9c463 100644
--- a/packages/animations/test/modal_test.dart
+++ b/packages/animations/test/modal_test.dart
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+import 'dart:ui' as ui;
+
import 'package:animations/src/modal.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
@@ -456,8 +458,90 @@
expect(find.byKey(topKey), findsNothing);
},
);
+
+ testWidgets(
+ 'showModal builds a new route with specified route settings',
+ (WidgetTester tester) async {
+ const RouteSettings routeSettings = RouteSettings(
+ name: 'route-name',
+ arguments: 'arguments',
+ );
+
+ final Widget button = Builder(builder: (BuildContext context) {
+ return Center(
+ child: ElevatedButton(
+ onPressed: () {
+ showModal<void>(
+ context: context,
+ configuration: _TestModalConfiguration(),
+ routeSettings: routeSettings,
+ builder: (BuildContext context) {
+ return const _FlutterLogoModal();
+ },
+ );
+ },
+ child: const Icon(Icons.add),
+ ),
+ );
+ });
+
+ await tester.pumpWidget(_boilerplate(button));
+ await tester.tap(find.byType(ElevatedButton));
+ await tester.pumpAndSettle();
+
+ // New route containing _FlutterLogoModal is present.
+ expect(find.byType(_FlutterLogoModal), findsOneWidget);
+
+ // Expect the last route pushed to the navigator to contain RouteSettings
+ // equal to the RouteSettings passed to showModal
+ final ModalRoute<dynamic> modalRoute = ModalRoute.of(
+ tester.element(find.byType(_FlutterLogoModal)),
+ )!;
+ expect(modalRoute.settings, routeSettings);
+ },
+ );
+
+ testWidgets(
+ 'showModal builds a new route with specified image filter',
+ (WidgetTester tester) async {
+ final ui.ImageFilter filter = ui.ImageFilter.blur(sigmaX: 1, sigmaY: 1);
+
+ final Widget button = Builder(builder: (BuildContext context) {
+ return Center(
+ child: ElevatedButton(
+ onPressed: () {
+ showModal<void>(
+ context: context,
+ configuration: _TestModalConfiguration(),
+ filter: filter,
+ builder: (BuildContext context) {
+ return const _FlutterLogoModal();
+ },
+ );
+ },
+ child: const Icon(Icons.add),
+ ),
+ );
+ });
+
+ await tester.pumpWidget(_boilerplate(button));
+ await tester.tap(find.byType(ElevatedButton));
+ await tester.pumpAndSettle();
+
+ // New route containing _FlutterLogoModal is present.
+ expect(find.byType(_FlutterLogoModal), findsOneWidget);
+ final BackdropFilter backdropFilter = tester.widget<BackdropFilter>(
+ find.byType(BackdropFilter),
+ );
+
+ // Verify new route's backdrop filter has been applied
+ expect(backdropFilter.filter, filter);
+ },
+ );
}
+Widget _boilerplate(Widget child) => MaterialApp(home: Scaffold(body: child));
+
double _getOpacity(GlobalKey key, WidgetTester tester) {
final Finder finder = find.ancestor(
of: find.byKey(key),
diff --git a/packages/animations/test/open_container_test.dart b/packages/animations/test/open_container_test.dart
index afc0eb2..10ae379 100644
--- a/packages/animations/test/open_container_test.dart
+++ b/packages/animations/test/open_container_test.dart
@@ -774,10 +774,7 @@
return const Text('Closed');
},
openBuilder: (BuildContext context, VoidCallback action) {
- return Switch(
- value: true,
- onChanged: (bool v) {},
- );
+ return const DummyStatefulWidget();
},
),
),
@@ -786,12 +783,12 @@
await tester.tap(find.text('Closed'));
await tester.pump(const Duration(milliseconds: 200));
- final State stateOpening = tester.state(find.byType(Switch));
+ final State stateOpening = tester.state(find.byType(DummyStatefulWidget));
expect(stateOpening, isNotNull);
await tester.pumpAndSettle();
expect(find.text('Closed'), findsNothing);
- final State stateOpen = tester.state(find.byType(Switch));
+ final State stateOpen = tester.state(find.byType(DummyStatefulWidget));
expect(stateOpen, isNotNull);
expect(stateOpen, same(stateOpening));
@@ -799,7 +796,7 @@
navigator.pop();
await tester.pump(const Duration(milliseconds: 200));
expect(find.text('Closed'), findsOneWidget);
- final State stateClosing = tester.state(find.byType(Switch));
+ final State stateClosing = tester.state(find.byType(DummyStatefulWidget));
expect(stateClosing, isNotNull);
expect(stateClosing, same(stateOpen));
});
@@ -811,10 +808,7 @@
child: OpenContainer(
closedBuilder: (BuildContext context, VoidCallback action) {
open = action;
- return Switch(
- value: true,
- onChanged: (bool v) {},
- );
+ return const DummyStatefulWidget();
},
openBuilder: (BuildContext context, VoidCallback action) {
return const Text('Open');
@@ -823,21 +817,21 @@
),
));
- final State stateClosed = tester.state(find.byType(Switch));
+ final State stateClosed = tester.state(find.byType(DummyStatefulWidget));
expect(stateClosed, isNotNull);
open();
await tester.pump(const Duration(milliseconds: 200));
expect(find.text('Open'), findsOneWidget);
- final State stateOpening = tester.state(find.byType(Switch));
+ final State stateOpening = tester.state(find.byType(DummyStatefulWidget));
expect(stateOpening, same(stateClosed));
await tester.pumpAndSettle();
- expect(find.byType(Switch), findsNothing);
+ expect(find.byType(DummyStatefulWidget), findsNothing);
expect(find.text('Open'), findsOneWidget);
final State stateOpen = tester.state(find.byType(
- Switch,
+ DummyStatefulWidget,
skipOffstage: false,
));
expect(stateOpen, same(stateOpening));
@@ -846,12 +840,13 @@
navigator.pop();
await tester.pump(const Duration(milliseconds: 200));
expect(find.text('Open'), findsOneWidget);
- final State stateClosing = tester.state(find.byType(Switch));
+ final State stateClosing = tester.state(find.byType(DummyStatefulWidget));
expect(stateClosing, same(stateOpen));
await tester.pumpAndSettle();
expect(find.text('Open'), findsNothing);
- final State stateClosedAgain = tester.state(find.byType(Switch));
+ final State stateClosedAgain =
+ tester.state(find.byType(DummyStatefulWidget));
expect(stateClosedAgain, same(stateClosing));
});
@@ -1966,3 +1961,15 @@
);
}
}
+
+class DummyStatefulWidget extends StatefulWidget {
+ const DummyStatefulWidget({Key? key}) : super(key: key);
+
+ @override
+ State<StatefulWidget> createState() => DummyState();
+}
+
+class DummyState extends State<DummyStatefulWidget> {
+ @override
+ Widget build(BuildContext context) => const SizedBox.expand();
+}
diff --git a/packages/multicast_dns/CHANGELOG.md b/packages/multicast_dns/CHANGELOG.md
index 267e730..fa64e26 100644
--- a/packages/multicast_dns/CHANGELOG.md
+++ b/packages/multicast_dns/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.3.0
+
+* Migrate package to null safety.
+
## 0.2.2
* Fixes parsing of TXT records. Continues parsing on non-utf8 strings.
diff --git a/packages/multicast_dns/lib/multicast_dns.dart b/packages/multicast_dns/lib/multicast_dns.dart
index 3b8fa47..148a4b0 100644
--- a/packages/multicast_dns/lib/multicast_dns.dart
+++ b/packages/multicast_dns/lib/multicast_dns.dart
@@ -48,14 +48,13 @@
bool _starting = false;
bool _started = false;
- RawDatagramSocket _incoming;
final List<RawDatagramSocket> _sockets = <RawDatagramSocket>[];
final LookupResolver _resolver = LookupResolver();
final ResourceRecordCache _cache = ResourceRecordCache();
final RawDatagramSocketFactory _rawDatagramSocketFactory;
- InternetAddress _mDnsAddress;
- int _mDnsPort;
+ InternetAddress? _mDnsAddress;
+ int? _mDnsPort;
/// Find all network interfaces with an the [InternetAddressType] specified.
static NetworkInterfacesFactory allInterfacesFactory =
@@ -82,14 +81,14 @@
/// for the mDNS query. If not provided, defaults to either `224.0.0.251` or
/// or `FF02::FB`.
Future<void> start({
- InternetAddress listenAddress,
- NetworkInterfacesFactory interfacesFactory,
+ InternetAddress? listenAddress,
+ NetworkInterfacesFactory? interfacesFactory,
int mDnsPort = mDnsPort,
- InternetAddress mDnsAddress,
+ InternetAddress? mDnsAddress,
}) async {
listenAddress ??= InternetAddress.anyIPv4;
interfacesFactory ??= allInterfacesFactory;
- _mDnsPort = mDnsPort;
+ final int selectedMDnsPort = _mDnsPort = mDnsPort;
_mDnsAddress = mDnsAddress;
assert(listenAddress.address == InternetAddress.anyIPv4.address ||
@@ -101,32 +100,32 @@
_starting = true;
// Listen on all addresses.
- _incoming = await _rawDatagramSocketFactory(
+ final RawDatagramSocket incoming = await _rawDatagramSocketFactory(
listenAddress.address,
- _mDnsPort,
+ selectedMDnsPort,
reuseAddress: true,
reusePort: true,
ttl: 255,
);
// Can't send to IPv6 any address.
- if (_incoming.address != InternetAddress.anyIPv6) {
- _sockets.add(_incoming);
+ if (incoming.address != InternetAddress.anyIPv6) {
+ _sockets.add(incoming);
}
- _mDnsAddress ??= _incoming.address.type == InternetAddressType.IPv4
+ _mDnsAddress ??= incoming.address.type == InternetAddressType.IPv4
? mDnsAddressIPv4
: mDnsAddressIPv6;
final List<NetworkInterface> interfaces =
- await interfacesFactory(listenAddress.type);
+ (await interfacesFactory(listenAddress.type)).toList();
for (NetworkInterface interface in interfaces) {
// Create a socket for sending on each adapter.
final InternetAddress targetAddress = interface.addresses[0];
final RawDatagramSocket socket = await _rawDatagramSocketFactory(
targetAddress,
- _mDnsPort,
+ selectedMDnsPort,
reuseAddress: true,
reusePort: true,
ttl: 255,
@@ -147,9 +146,9 @@
));
}
// Join multicast on this interface.
- _incoming.joinMulticast(_mDnsAddress, interface);
+ incoming.joinMulticast(_mDnsAddress!, interface);
}
- _incoming.listen(_handleIncoming);
+ incoming.listen((RawSocketEvent event) => _handleIncoming(event, incoming));
_started = true;
_starting = false;
}
@@ -186,7 +185,8 @@
ResourceRecordQuery query, {
Duration timeout = const Duration(seconds: 5),
}) {
- if (!_started) {
+ final int? selectedMDnsPort = _mDnsPort;
+ if (!_started || selectedMDnsPort == null) {
throw StateError('mDNS client must be started before calling lookup.');
}
// Look for entries in the cache.
@@ -207,18 +207,21 @@
// Send the request on all interfaces.
final List<int> packet = query.encode();
for (RawDatagramSocket socket in _sockets) {
- socket.send(packet, _mDnsAddress, _mDnsPort);
+ socket.send(packet, _mDnsAddress!, selectedMDnsPort);
}
return results;
}
// Process incoming datagrams.
- void _handleIncoming(RawSocketEvent event) {
+ void _handleIncoming(RawSocketEvent event, RawDatagramSocket incoming) {
if (event == RawSocketEvent.read) {
- final Datagram datagram = _incoming.receive();
+ final Datagram? datagram = incoming.receive();
+ if (datagram == null) {
+ return;
+ }
// Check for published responses.
- final List<ResourceRecord> response = decodeMDnsResponse(datagram.data);
+ final List<ResourceRecord>? response = decodeMDnsResponse(datagram.data);
if (response != null) {
_cache.updateRecords(response);
_resolver.handleResponse(response);
diff --git a/packages/multicast_dns/lib/src/constants.dart b/packages/multicast_dns/lib/src/constants.dart
index 2a22264..061329d 100644
--- a/packages/multicast_dns/lib/src/constants.dart
+++ b/packages/multicast_dns/lib/src/constants.dart
@@ -14,20 +14,20 @@
const int mDnsPort = 5353;
/// Enumeration of supported resource record class types.
-class ResourceRecordClass {
+abstract class ResourceRecordClass {
// This class is intended to be used as a namespace, and should not be
// extended directly.
- factory ResourceRecordClass._() => null;
+ ResourceRecordClass._();
/// Internet address class ("IN").
static const int internet = 1;
}
/// Enumeration of DNS question types.
-class QuestionType {
+abstract class QuestionType {
// This class is intended to be used as a namespace, and should not be
// extended directly.
- factory QuestionType._() => null;
+ QuestionType._();
/// "QU" Question.
static const int unicast = 0x8000;
diff --git a/packages/multicast_dns/lib/src/lookup_resolver.dart b/packages/multicast_dns/lib/src/lookup_resolver.dart
index b374e9f..40cc86b 100644
--- a/packages/multicast_dns/lib/src/lookup_resolver.dart
+++ b/packages/multicast_dns/lib/src/lookup_resolver.dart
@@ -25,7 +25,7 @@
final StreamController<ResourceRecord> controller;
/// The timer for the request.
- Timer timer;
+ Timer? timer;
}
/// Class for keeping track of pending lookups and processing incoming
@@ -89,7 +89,7 @@
while (_pendingRequests.isNotEmpty) {
final PendingRequest request = _pendingRequests.first;
request.unlink();
- request.timer.cancel();
+ request.timer?.cancel();
request.controller.close();
}
}
diff --git a/packages/multicast_dns/lib/src/native_protocol_client.dart b/packages/multicast_dns/lib/src/native_protocol_client.dart
index 553d564..734412b 100644
--- a/packages/multicast_dns/lib/src/native_protocol_client.dart
+++ b/packages/multicast_dns/lib/src/native_protocol_client.dart
@@ -29,7 +29,7 @@
for (final SplayTreeMap<String, List<ResourceRecord>> map
in _cache.values) {
for (final List<ResourceRecord> records in map.values) {
- count += records?.length;
+ count += records.length;
}
}
return count;
@@ -45,14 +45,15 @@
// TODO(dnfield): Update this to use set literal syntax when we're able to bump the SDK constraint.
seenRecordTypes[record.resourceRecordType] ??=
Set<String>(); // ignore: prefer_collection_literals
- if (seenRecordTypes[record.resourceRecordType].add(record.name)) {
+ if (seenRecordTypes[record.resourceRecordType]!.add(record.name)) {
_cache[record.resourceRecordType] ??=
SplayTreeMap<String, List<ResourceRecord>>();
- _cache[record.resourceRecordType]
- [record.name] = <ResourceRecord>[record];
+ _cache[record.resourceRecordType]![record.name] = <ResourceRecord>[
+ record
+ ];
} else {
- _cache[record.resourceRecordType][record.name].add(record);
+ _cache[record.resourceRecordType]![record.name]!.add(record);
}
}
}
@@ -62,12 +63,12 @@
String name, int type, List<T> results) {
assert(ResourceRecordType.debugAssertValid(type));
final int time = DateTime.now().millisecondsSinceEpoch;
- final SplayTreeMap<String, List<ResourceRecord>> candidates = _cache[type];
+ final SplayTreeMap<String, List<ResourceRecord>>? candidates = _cache[type];
if (candidates == null) {
return;
}
- final List<ResourceRecord> candidateRecords = candidates[name];
+ final List<ResourceRecord>? candidateRecords = candidates[name];
if (candidateRecords == null) {
return;
}
diff --git a/packages/multicast_dns/lib/src/packet.dart b/packages/multicast_dns/lib/src/packet.dart
index 2dae398..9905689 100644
--- a/packages/multicast_dns/lib/src/packet.dart
+++ b/packages/multicast_dns/lib/src/packet.dart
@@ -23,7 +23,6 @@
/// Will attempt to append 'local' if the name is something like '_http._tcp',
/// and '._tcp.local' if name is something like '_http'.
List<String> processDnsNameParts(String name) {
- assert(name != null);
final List<String> parts = name.split('.');
if (parts.length == 1) {
return <String>[parts[0], '_tcp', 'local'];
@@ -47,9 +46,7 @@
int type = ResourceRecordType.addressIPv4,
bool multicast = true,
}) {
- assert(name != null);
assert(ResourceRecordType.debugAssertValid(type));
- assert(multicast != null);
final List<String> nameParts = processDnsNameParts(name);
final List<List<int>> rawNameParts =
@@ -179,7 +176,7 @@
/// If decoding fails (e.g. due to an invalid packet), `null` is returned.
///
/// See https://tools.ietf.org/html/rfc1035 for format.
-ResourceRecordQuery decodeMDnsQuery(List<int> packet) {
+ResourceRecordQuery? decodeMDnsQuery(List<int> packet) {
final int length = packet.length;
if (length < _kHeaderSize) {
return null;
@@ -214,7 +211,7 @@
/// If decoding fails (e.g. due to an invalid packet) `null` is returned.
///
/// See https://tools.ietf.org/html/rfc1035 for the format.
-List<ResourceRecord> decodeMDnsResponse(List<int> packet) {
+List<ResourceRecord>? decodeMDnsResponse(List<int> packet) {
final int length = packet.length;
if (length < _kHeaderSize) {
return null;
@@ -242,7 +239,7 @@
}
}
- ResourceRecord readResourceRecord() {
+ ResourceRecord? readResourceRecord() {
// First read the FQDN.
final _FQDNReadResult result = _readFQDN(data, packetBytes, offset, length);
final String fqdn = result.fqdn;
@@ -319,7 +316,6 @@
priority: priority,
weight: weight,
);
- break;
case ResourceRecordType.serverPointer:
checkLength(offset + readDataLength);
final _FQDNReadResult result =
@@ -373,7 +369,7 @@
offset += 4;
}
for (int i = 0; i < remainingCount; i++) {
- final ResourceRecord record = readResourceRecord();
+ final ResourceRecord? record = readResourceRecord();
if (record != null) {
result.add(record);
}
@@ -391,7 +387,7 @@
/// specified [offset].
///
/// The [offset] parameter should not be null.
- const MDnsDecodeException(this.offset) : assert(offset != null);
+ const MDnsDecodeException(this.offset);
/// The offset in the packet at which the exception occurred.
final int offset;
diff --git a/packages/multicast_dns/lib/src/resource_record.dart b/packages/multicast_dns/lib/src/resource_record.dart
index e4be5f3..eae21bf 100644
--- a/packages/multicast_dns/lib/src/resource_record.dart
+++ b/packages/multicast_dns/lib/src/resource_record.dart
@@ -6,7 +6,6 @@
import 'dart:io';
import 'dart:typed_data';
-import 'package:meta/meta.dart';
import 'package:multicast_dns/src/constants.dart';
import 'package:multicast_dns/src/packet.dart';
@@ -19,7 +18,6 @@
(current & _multipleHashPrime) ^ hash;
int _hashValues(List<int> values) {
- assert(values != null);
assert(values.isNotEmpty);
return values.fold(
@@ -29,10 +27,10 @@
}
/// Enumeration of support resource record types.
-class ResourceRecordType {
+abstract class ResourceRecordType {
// This class is intended to be used as a namespace, and should not be
// extended directly.
- factory ResourceRecordType._() => null;
+ ResourceRecordType._();
/// An IPv4 Address record, also known as an "A" record. It has a value of 1.
static const int addressIPv4 = 1;
@@ -94,8 +92,7 @@
this.resourceRecordType,
this.fullyQualifiedName,
this.questionType,
- ) : assert(fullyQualifiedName != null),
- assert(ResourceRecordType.debugAssertValid(resourceRecordType));
+ ) : assert(ResourceRecordType.debugAssertValid(resourceRecordType));
/// An A (IPv4) query.
ResourceRecordQuery.addressIPv4(
@@ -191,8 +188,7 @@
/// Base implementation of DNS resource records (RRs).
abstract class ResourceRecord {
/// Creates a new ResourceRecord.
- const ResourceRecord(this.resourceRecordType, this.name, this.validUntil)
- : assert(name != null);
+ const ResourceRecord(this.resourceRecordType, this.name, this.validUntil);
/// The FQDN for this record.
final String name;
@@ -207,14 +203,13 @@
@override
String toString() =>
- '$runtimeType{$name, validUntil: ${DateTime.fromMillisecondsSinceEpoch(validUntil ?? 0)}, $_additionalInfo}';
+ '$runtimeType{$name, validUntil: ${DateTime.fromMillisecondsSinceEpoch(validUntil)}, $_additionalInfo}';
@override
bool operator ==(Object other) {
- return other.runtimeType == runtimeType && _equals(other);
+ return other is ResourceRecord && _equals(other);
}
- @protected
bool _equals(ResourceRecord other) {
return other.name == name &&
other.validUntil == validUntil &&
@@ -233,7 +228,6 @@
// Subclasses of this class should use _hashValues to create a hash code
// that will then get hashed in with the common values on this class.
- @protected
int get _hashCode;
/// Low level method for encoding this record into an mDNS packet.
@@ -250,9 +244,8 @@
PtrResourceRecord(
String name,
int validUntil, {
- @required this.domainName,
- }) : assert(domainName != null),
- super(ResourceRecordType.serverPointer, name, validUntil);
+ required this.domainName,
+ }) : super(ResourceRecordType.serverPointer, name, validUntil);
/// The FQDN for this record.
final String domainName;
@@ -282,7 +275,7 @@
IPAddressResourceRecord(
String name,
int validUntil, {
- @required this.address,
+ required this.address,
}) : super(
address.type == InternetAddressType.IPv4
? ResourceRecordType.addressIPv4
@@ -316,15 +309,11 @@
SrvResourceRecord(
String name,
int validUntil, {
- @required this.target,
- @required this.port,
- @required this.priority,
- @required this.weight,
- }) : assert(target != null),
- assert(port != null),
- assert(priority != null),
- assert(weight != null),
- super(ResourceRecordType.service, name, validUntil);
+ required this.target,
+ required this.port,
+ required this.priority,
+ required this.weight,
+ }) : super(ResourceRecordType.service, name, validUntil);
/// The hostname for this record.
final String target;
@@ -378,9 +367,8 @@
TxtResourceRecord(
String name,
int validUntil, {
- @required this.text,
- }) : assert(text != null),
- super(ResourceRecordType.text, name, validUntil);
+ required this.text,
+ }) : super(ResourceRecordType.text, name, validUntil);
/// The raw text from this record.
final String text;
diff --git a/packages/multicast_dns/pubspec.yaml b/packages/multicast_dns/pubspec.yaml
index 98c75ae..d59445f 100644
--- a/packages/multicast_dns/pubspec.yaml
+++ b/packages/multicast_dns/pubspec.yaml
@@ -1,14 +1,10 @@
name: multicast_dns
description: Dart package for mDNS queries (e.g. Bonjour, Avahi).
homepage: https://github.com/flutter/packages/tree/master/packages/multicast_dns
-version: 0.2.2
-
-dependencies:
- meta: ^1.1.6
+version: 0.3.0
dev_dependencies:
- mockito: "^4.1.0"
- test: "^1.3.4"
+ test: "^1.16.5"
environment:
- sdk: ">=2.2.0 <3.0.0"
+ sdk: ">=2.12.0-0 <3.0.0"
diff --git a/packages/multicast_dns/test/client_test.dart b/packages/multicast_dns/test/client_test.dart
index f327c20..85ab0b1 100644
--- a/packages/multicast_dns/test/client_test.dart
+++ b/packages/multicast_dns/test/client_test.dart
@@ -2,23 +2,25 @@
// for details. 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:io';
import 'package:multicast_dns/multicast_dns.dart';
-import 'package:mockito/mockito.dart';
+import 'package:test/fake.dart';
import 'package:test/test.dart';
void main() {
test('Can inject datagram socket factory and configure mdns port', () async {
- int lastPort;
- final MockRawDatagramSocket mockRawDatagramSocket = MockRawDatagramSocket();
+ late int lastPort;
+ final FakeRawDatagramSocket datagramSocket = FakeRawDatagramSocket();
final MDnsClient client = MDnsClient(rawDatagramSocketFactory:
(dynamic host, int port,
- {bool reuseAddress, bool reusePort, int ttl = 1}) async {
+ {bool reuseAddress = true,
+ bool reusePort = true,
+ int ttl = 1}) async {
lastPort = port;
- return mockRawDatagramSocket;
+ return datagramSocket;
});
- when(mockRawDatagramSocket.address).thenReturn(InternetAddress.anyIPv4);
await client.start(
mDnsPort: 1234,
@@ -29,4 +31,17 @@
});
}
-class MockRawDatagramSocket extends Mock implements RawDatagramSocket {}
+class FakeRawDatagramSocket extends Fake implements RawDatagramSocket {
+ @override
+ InternetAddress get address => InternetAddress.anyIPv4;
+
+ @override
+ StreamSubscription<RawSocketEvent> listen(
+ void Function(RawSocketEvent event)? onData,
+ {Function? onError,
+ void Function()? onDone,
+ bool? cancelOnError}) {
+ return const Stream<RawSocketEvent>.empty().listen(onData,
+ onError: onError, cancelOnError: cancelOnError, onDone: onDone);
+ }
+}
diff --git a/packages/multicast_dns/test/decode_test.dart b/packages/multicast_dns/test/decode_test.dart
index f11f4d9..e8c1afa 100644
--- a/packages/multicast_dns/test/decode_test.dart
+++ b/packages/multicast_dns/test/decode_test.dart
@@ -21,23 +21,23 @@
void testValidPackages() {
test('Can decode valid packets', () {
- List<ResourceRecord> result = decodeMDnsResponse(package1);
+ List<ResourceRecord> result = decodeMDnsResponse(package1)!;
expect(result, isNotNull);
expect(result.length, 1);
- IPAddressResourceRecord ipResult = result[0];
+ IPAddressResourceRecord ipResult = result[0] as IPAddressResourceRecord;
expect(ipResult.name, 'raspberrypi.local');
expect(ipResult.address.address, '192.168.1.191');
- result = decodeMDnsResponse(package2);
+ result = decodeMDnsResponse(package2)!;
expect(result.length, 2);
- ipResult = result[0];
+ ipResult = result[0] as IPAddressResourceRecord;
expect(ipResult.name, 'raspberrypi.local');
expect(ipResult.address.address, '192.168.1.191');
- ipResult = result[1];
+ ipResult = result[1] as IPAddressResourceRecord;
expect(ipResult.name, 'raspberrypi.local');
expect(ipResult.address.address, '169.254.95.83');
- result = decodeMDnsResponse(package3);
+ result = decodeMDnsResponse(package3)!;
expect(result.length, 8);
expect(result, <ResourceRecord>[
TxtResourceRecord(
@@ -85,7 +85,7 @@
),
]);
- result = decodeMDnsResponse(packagePtrResponse);
+ result = decodeMDnsResponse(packagePtrResponse)!;
expect(6, result.length);
expect(result, <ResourceRecord>[
PtrResourceRecord(
@@ -127,7 +127,7 @@
// Fixes https://github.com/flutter/flutter/issues/31854
test('Can decode packages with question, answer and additional', () {
final List<ResourceRecord> result =
- decodeMDnsResponse(packetWithQuestionAnArCount);
+ decodeMDnsResponse(packetWithQuestionAnArCount)!;
expect(result, isNotNull);
expect(result.length, 2);
expect(result, <ResourceRecord>[
@@ -148,7 +148,7 @@
test('Can decode packages without question and with answer and additional',
() {
final List<ResourceRecord> result =
- decodeMDnsResponse(packetWithoutQuestionWithAnArCount);
+ decodeMDnsResponse(packetWithoutQuestionWithAnArCount)!;
expect(result, isNotNull);
expect(result.length, 2);
expect(result, <ResourceRecord>[
@@ -166,7 +166,7 @@
});
test('Can decode packages with a long text resource', () {
- final List<ResourceRecord> result = decodeMDnsResponse(packetWithLongTxt);
+ final List<ResourceRecord> result = decodeMDnsResponse(packetWithLongTxt)!;
expect(result, isNotNull);
expect(result.length, 2);
expect(result, <ResourceRecord>[
@@ -210,10 +210,10 @@
void testNonUtf8DomainName() {
test('Returns non-null for non-utf8 domain name', () {
- final List<ResourceRecord> result = decodeMDnsResponse(nonUtf8Package);
+ final List<ResourceRecord> result = decodeMDnsResponse(nonUtf8Package)!;
expect(result, isNotNull);
expect(result[0] is TxtResourceRecord, isTrue);
- final TxtResourceRecord txt = result[0];
+ final TxtResourceRecord txt = result[0] as TxtResourceRecord;
expect(txt.name, contains('�'));
});
}
diff --git a/packages/multicast_dns/test/lookup_resolver_test.dart b/packages/multicast_dns/test/lookup_resolver_test.dart
index 6a311fd..3423a68 100644
--- a/packages/multicast_dns/test/lookup_resolver_test.dart
+++ b/packages/multicast_dns/test/lookup_resolver_test.dart
@@ -40,7 +40,8 @@
final ResourceRecord response =
ip4Result('xxx.local', InternetAddress('1.2.3.4'));
resolver.handleResponse(<ResourceRecord>[response]);
- final IPAddressResourceRecord result = await futureResult.first;
+ final IPAddressResourceRecord result =
+ await futureResult.first as IPAddressResourceRecord;
expect('1.2.3.4', result.address.address);
resolver.clearPendingRequests();
});
@@ -59,8 +60,10 @@
final ResourceRecord response2 =
ip4Result('yyy.local', InternetAddress('2.3.4.5'));
resolver.handleResponse(<ResourceRecord>[response2, response1]);
- final IPAddressResourceRecord result1 = await futureResult1.first;
- final IPAddressResourceRecord result2 = await futureResult2.first;
+ final IPAddressResourceRecord result1 =
+ await futureResult1.first as IPAddressResourceRecord;
+ final IPAddressResourceRecord result2 =
+ await futureResult2.first as IPAddressResourceRecord;
expect('1.2.3.4', result1.address.address);
expect('2.3.4.5', result2.address.address);
resolver.clearPendingRequests();
@@ -88,8 +91,10 @@
resolver.handleResponse(<ResourceRecord>[response0]);
resolver.handleResponse(<ResourceRecord>[response2, response1]);
resolver.handleResponse(<ResourceRecord>[response0]);
- final IPAddressResourceRecord result1 = await futureResult1.first;
- final IPAddressResourceRecord result2 = await futureResult2.first;
+ final IPAddressResourceRecord result1 =
+ await futureResult1.first as IPAddressResourceRecord;
+ final IPAddressResourceRecord result2 =
+ await futureResult2.first as IPAddressResourceRecord;
expect('1.2.3.4', result1.address.address);
expect('2.3.4.5', result2.address.address);
resolver.clearPendingRequests();
diff --git a/packages/pigeon/CHANGELOG.md b/packages/pigeon/CHANGELOG.md
index 2c96dc7..0e5faee 100644
--- a/packages/pigeon/CHANGELOG.md
+++ b/packages/pigeon/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 0.1.21
+
+* Fixed decode method on generated Flutter classes that use null-safety and have
+ null values.
+
## 0.1.20
* Implemented `@async` HostApi's for iOS.
diff --git a/packages/pigeon/lib/dart_generator.dart b/packages/pigeon/lib/dart_generator.dart
index 6cf834d..ca94c97 100644
--- a/packages/pigeon/lib/dart_generator.dart
+++ b/packages/pigeon/lib/dart_generator.dart
@@ -178,11 +178,11 @@
String _addGenericTypes(String dataType, String nullTag) {
switch (dataType) {
case 'List':
- return 'List<Object$nullTag>';
+ return 'List<Object$nullTag>$nullTag';
case 'Map':
- return 'Map<Object$nullTag, Object$nullTag>';
+ return 'Map<Object$nullTag, Object$nullTag>$nullTag';
default:
- return dataType;
+ return '$dataType$nullTag';
}
}
@@ -211,8 +211,7 @@
sink.write('class ${klass.name} ');
indent.scoped('{', '}', () {
for (Field field in klass.fields) {
- final String datatype =
- '${_addGenericTypes(field.dataType, nullTag)}$nullTag';
+ final String datatype = '${_addGenericTypes(field.dataType, nullTag)}';
indent.writeln('$datatype ${field.name};');
}
if (klass.fields.isNotEmpty) {
diff --git a/packages/pigeon/lib/generator_tools.dart b/packages/pigeon/lib/generator_tools.dart
index 996e794..d196e26 100644
--- a/packages/pigeon/lib/generator_tools.dart
+++ b/packages/pigeon/lib/generator_tools.dart
@@ -8,7 +8,7 @@
import 'ast.dart';
/// The current version of pigeon. This must match the version in pubspec.yaml.
-const String pigeonVersion = '0.1.20';
+const String pigeonVersion = '0.1.21';
/// Read all the content from [stdin] to a String.
String readStdin() {
diff --git a/packages/pigeon/lib/java_generator.dart b/packages/pigeon/lib/java_generator.dart
index 68f61f6..c79a18e 100644
--- a/packages/pigeon/lib/java_generator.dart
+++ b/packages/pigeon/lib/java_generator.dart
@@ -14,8 +14,8 @@
'Int32List': 'int[]',
'Int64List': 'long[]',
'Float64List': 'double[]',
- 'List': 'ArrayList',
- 'Map': 'HashMap',
+ 'List': 'List<Object>',
+ 'Map': 'Map<String, Object>',
};
/// Options that control how Java code will be generated.
@@ -77,15 +77,14 @@
indent.scoped('{', '});', () {
final String argType = method.argType;
final String returnType = method.returnType;
- indent.writeln(
- 'HashMap<String, HashMap> wrapped = new HashMap<>();');
+ indent.writeln('Map<String, Object> wrapped = new HashMap<>();');
indent.write('try ');
indent.scoped('{', '}', () {
final List<String> methodArgument = <String>[];
if (argType != 'void') {
indent.writeln('@SuppressWarnings("ConstantConditions")');
indent.writeln(
- '$argType input = $argType.fromMap((HashMap)message);');
+ '$argType input = $argType.fromMap((Map<String, Object>)message);');
methodArgument.add('input');
}
if (method.isAsynchronous) {
@@ -168,20 +167,40 @@
indent.dec();
indent.dec();
if (func.argType != 'void') {
- indent.writeln('HashMap inputMap = argInput.toMap();');
+ indent.writeln('Map<String, Object> inputMap = argInput.toMap();');
}
- indent.write('channel.send($sendArgument, channelReply -> ');
- indent.scoped('{', '});', () {
- if (func.returnType == 'void') {
- indent.writeln('callback.reply(null);');
- } else {
- indent.writeln('HashMap outputMap = (HashMap)channelReply;');
- indent.writeln('@SuppressWarnings("ConstantConditions")');
- indent.writeln(
- '${func.returnType} output = ${func.returnType}.fromMap(outputMap);');
- indent.writeln('callback.reply(output);');
- }
+ indent.write('if (callback != null)');
+ indent.scoped('{', '}', () {
+ indent.write('channel.send($sendArgument, channelReply -> ');
+ indent.scoped('{', '});', () {
+ if (func.returnType == 'void') {
+ indent.writeln('callback.reply(null);');
+ } else {
+ indent.writeln('Map outputMap = (Map)channelReply;');
+ indent.writeln('@SuppressWarnings("ConstantConditions")');
+ indent.writeln(
+ '${func.returnType} output = ${func.returnType}.fromMap(outputMap);');
+ indent.writeln('callback.reply(output);');
+ }
+ });
});
+ indent.write(' else ');
+ indent.scoped('{', '}', () {
+ indent.writeln('channel.send($sendArgument, null);');
+ });
+ });
+
+ if (func.argType == 'void') {
+ indent.write('public void ${func.name}() ');
+ } else {
+ indent.write('public void ${func.name}(${func.argType} argInput) ');
+ }
+ indent.scoped('{', '}', () {
+ if (func.argType == 'void') {
+ indent.writeln('${func.name}(null);');
+ } else {
+ indent.writeln('${func.name}(argInput, null);');
+ }
});
}
});
@@ -210,7 +229,7 @@
return '($varName == null) ? null : (($varName instanceof Integer) ? (Integer)$varName : (${hostDatatype.datatype})$varName)';
} else if (!hostDatatype.isBuiltin &&
classes.map((Class x) => x.name).contains(field.dataType)) {
- return '${hostDatatype.datatype}.fromMap((HashMap)$varName)';
+ return '${hostDatatype.datatype}.fromMap((Map)$varName)';
} else {
return '(${hostDatatype.datatype})$varName';
}
@@ -232,13 +251,15 @@
indent.writeln('import io.flutter.plugin.common.BasicMessageChannel;');
indent.writeln('import io.flutter.plugin.common.BinaryMessenger;');
indent.writeln('import io.flutter.plugin.common.StandardMessageCodec;');
- indent.writeln('import java.util.ArrayList;');
+ indent.writeln('import java.util.List;');
+ indent.writeln('import java.util.Map;');
indent.writeln('import java.util.HashMap;');
indent.addln('');
assert(options.className != null);
indent.writeln('/** Generated class from Pigeon. */');
- indent.writeln('@SuppressWarnings("unused")');
+ indent.writeln(
+ '@SuppressWarnings({"unused", "unchecked", "CodeBlock2Expr", "RedundantSuppression"})');
indent.write('public class ${options.className} ');
indent.scoped('{', '}', () {
for (Class klass in root.classes) {
@@ -257,10 +278,9 @@
'public void ${_makeSetter(field)}(${hostDatatype.datatype} setterArg) { this.${field.name} = setterArg; }');
indent.addln('');
}
- indent.write('HashMap toMap() ');
+ indent.write('Map<String, Object> toMap() ');
indent.scoped('{', '}', () {
- indent.writeln(
- 'HashMap<String, Object> toMapResult = new HashMap<>();');
+ indent.writeln('Map<String, Object> toMapResult = new HashMap<>();');
for (Field field in klass.fields) {
final HostDatatype hostDatatype =
getHostDatatype(field, root.classes, _javaTypeForDartType);
@@ -275,7 +295,7 @@
}
indent.writeln('return toMapResult;');
});
- indent.write('static ${klass.name} fromMap(HashMap map) ');
+ indent.write('static ${klass.name} fromMap(Map<String, Object> map) ');
indent.scoped('{', '}', () {
indent.writeln('${klass.name} fromMapResult = new ${klass.name}();');
for (Field field in klass.fields) {
@@ -297,8 +317,9 @@
}
}
- indent.format('''private static HashMap wrapError(Exception exception) {
-\tHashMap<String, Object> errorMap = new HashMap<>();
+ indent.format(
+ '''private static Map<String, Object> wrapError(Exception exception) {
+\tMap<String, Object> errorMap = new HashMap<>();
\terrorMap.put("${Keys.errorMessage}", exception.toString());
\terrorMap.put("${Keys.errorCode}", exception.getClass().getSimpleName());
\terrorMap.put("${Keys.errorDetails}", null);
diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/.gitignore b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/.gitignore
new file mode 100644
index 0000000..0fa6b67
--- /dev/null
+++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/.gitignore
@@ -0,0 +1,46 @@
+# Miscellaneous
+*.class
+*.log
+*.pyc
+*.swp
+.DS_Store
+.atom/
+.buildlog/
+.history
+.svn/
+
+# IntelliJ related
+*.iml
+*.ipr
+*.iws
+.idea/
+
+# The .vscode folder contains launch configuration and tasks you configure in
+# VS Code which you may wish to be included in version control, so this line
+# is commented out by default.
+#.vscode/
+
+# Flutter/Dart/Pub related
+**/doc/api/
+**/ios/Flutter/.last_build_id
+.dart_tool/
+.flutter-plugins
+.flutter-plugins-dependencies
+.packages
+.pub-cache/
+.pub/
+/build/
+
+# Web related
+lib/generated_plugin_registrant.dart
+
+# Symbolication related
+app.*.symbols
+
+# Obfuscation related
+app.*.map.json
+
+# Android Studio will place build artifacts here
+/android/app/debug
+/android/app/profile
+/android/app/release
diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/.metadata b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/.metadata
new file mode 100644
index 0000000..5db57c1
--- /dev/null
+++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/.metadata
@@ -0,0 +1,10 @@
+# This file tracks properties of this Flutter project.
+# Used by Flutter tool to assess capabilities and perform upgrades etc.
+#
+# This file should be version controlled and should not be manually edited.
+
+version:
+ revision: 6db3d61ed4a58ba89140d7fe1fd294b598cc29c5
+ channel: master
+
+project_type: app
diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/README.md b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/README.md
new file mode 100644
index 0000000..3c52fc9
--- /dev/null
+++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/README.md
@@ -0,0 +1,3 @@
+# flutter_unit_tests
+
+Unit test scaffold for null safe Flutter projects.
diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_safe_pigeon.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_safe_pigeon.dart
new file mode 100644
index 0000000..455058d
--- /dev/null
+++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_safe_pigeon.dart
@@ -0,0 +1,166 @@
+// Autogenerated from Pigeon (v0.1.21), do not edit directly.
+// See also: https://pub.dev/packages/pigeon
+// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import
+// @dart = 2.12
+import 'dart:async';
+import 'dart:typed_data' show Uint8List, Int32List, Int64List, Float64List;
+
+import 'package:flutter/services.dart';
+
+class SearchReply {
+ String? result;
+ String? error;
+
+ Object encode() {
+ final Map<Object?, Object?> pigeonMap = <Object?, Object?>{};
+ pigeonMap['result'] = result;
+ pigeonMap['error'] = error;
+ return pigeonMap;
+ }
+
+ static SearchReply decode(Object message) {
+ final Map<Object?, Object?> pigeonMap = message as Map<Object?, Object?>;
+ return SearchReply()
+ ..result = pigeonMap['result'] as String?
+ ..error = pigeonMap['error'] as String?;
+ }
+}
+
+class SearchRequest {
+ String? query;
+ int? anInt;
+ bool? aBool;
+
+ Object encode() {
+ final Map<Object?, Object?> pigeonMap = <Object?, Object?>{};
+ pigeonMap['query'] = query;
+ pigeonMap['anInt'] = anInt;
+ pigeonMap['aBool'] = aBool;
+ return pigeonMap;
+ }
+
+ static SearchRequest decode(Object message) {
+ final Map<Object?, Object?> pigeonMap = message as Map<Object?, Object?>;
+ return SearchRequest()
+ ..query = pigeonMap['query'] as String?
+ ..anInt = pigeonMap['anInt'] as int?
+ ..aBool = pigeonMap['aBool'] as bool?;
+ }
+}
+
+class Nested {
+ SearchRequest? request;
+
+ Object encode() {
+ final Map<Object?, Object?> pigeonMap = <Object?, Object?>{};
+ pigeonMap['request'] = request == null ? null : request!.encode();
+ return pigeonMap;
+ }
+
+ static Nested decode(Object message) {
+ final Map<Object?, Object?> pigeonMap = message as Map<Object?, Object?>;
+ return Nested()
+ ..request = pigeonMap['request'] != null
+ ? SearchRequest.decode(pigeonMap['request']!)
+ : null;
+ }
+}
+
+abstract class FlutterSearchApi {
+ SearchReply search(SearchRequest arg);
+ static void setup(FlutterSearchApi? api) {
+ {
+ const BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+ 'dev.flutter.pigeon.FlutterSearchApi.search', StandardMessageCodec());
+ if (api == null) {
+ channel.setMessageHandler(null);
+ } else {
+ channel.setMessageHandler((Object? message) async {
+ assert(message != null,
+ 'Argument for dev.flutter.pigeon.FlutterSearchApi.search was null. Expected SearchRequest.');
+ final SearchRequest input = SearchRequest.decode(message!);
+ final SearchReply output = api.search(input);
+ return output.encode();
+ });
+ }
+ }
+ }
+}
+
+class NestedApi {
+ Future<SearchReply> search(Nested arg) async {
+ final Object encoded = arg.encode();
+ const BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+ 'dev.flutter.pigeon.NestedApi.search', StandardMessageCodec());
+ final Map<Object?, Object?>? replyMap =
+ await channel.send(encoded) as Map<Object?, Object?>?;
+ if (replyMap == null) {
+ throw PlatformException(
+ code: 'channel-error',
+ message: 'Unable to establish connection on channel.',
+ details: null,
+ );
+ } else if (replyMap['error'] != null) {
+ final Map<Object?, Object?> error =
+ replyMap['error'] as Map<Object?, Object?>;
+ throw PlatformException(
+ code: error['code'] as String,
+ message: error['message'] as String?,
+ details: error['details'],
+ );
+ } else {
+ return SearchReply.decode(replyMap['result']!);
+ }
+ }
+}
+
+class Api {
+ Future<void> initialize() async {
+ const BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+ 'dev.flutter.pigeon.Api.initialize', StandardMessageCodec());
+ final Map<Object?, Object?>? replyMap =
+ await channel.send(null) as Map<Object?, Object?>?;
+ if (replyMap == null) {
+ throw PlatformException(
+ code: 'channel-error',
+ message: 'Unable to establish connection on channel.',
+ details: null,
+ );
+ } else if (replyMap['error'] != null) {
+ final Map<Object?, Object?> error =
+ replyMap['error'] as Map<Object?, Object?>;
+ throw PlatformException(
+ code: error['code'] as String,
+ message: error['message'] as String?,
+ details: error['details'],
+ );
+ } else {
+ // noop
+ }
+ }
+
+ Future<SearchReply> search(SearchRequest arg) async {
+ final Object encoded = arg.encode();
+ const BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+ 'dev.flutter.pigeon.Api.search', StandardMessageCodec());
+ final Map<Object?, Object?>? replyMap =
+ await channel.send(encoded) as Map<Object?, Object?>?;
+ if (replyMap == null) {
+ throw PlatformException(
+ code: 'channel-error',
+ message: 'Unable to establish connection on channel.',
+ details: null,
+ );
+ } else if (replyMap['error'] != null) {
+ final Map<Object?, Object?> error =
+ replyMap['error'] as Map<Object?, Object?>;
+ throw PlatformException(
+ code: error['code'] as String,
+ message: error['message'] as String?,
+ details: error['details'],
+ );
+ } else {
+ return SearchReply.decode(replyMap['result']!);
+ }
+ }
+}
diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/pubspec.yaml b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/pubspec.yaml
new file mode 100644
index 0000000..32058de
--- /dev/null
+++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/pubspec.yaml
@@ -0,0 +1,17 @@
+name: flutter_unit_tests
+description: Unit test scaffold for null safe Flutter projects.
+publish_to: 'none' # Remove this line if you wish to publish to pub.dev
+version: 1.0.0+1
+environment:
+ sdk: ">=2.12.0 <3.0.0"
+
+dependencies:
+ flutter:
+ sdk: flutter
+
+dev_dependencies:
+ flutter_test:
+ sdk: flutter
+
+flutter:
+ uses-material-design: true
diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/test/null_safe_test.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/test/null_safe_test.dart
new file mode 100644
index 0000000..523127a
--- /dev/null
+++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/test/null_safe_test.dart
@@ -0,0 +1,28 @@
+// Copyright 2020 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 'package:flutter_unit_tests/null_safe_pigeon.dart';
+import 'package:flutter_test/flutter_test.dart';
+
+void main() {
+ test('with values filled', () {
+ final SearchReply reply = SearchReply()
+ ..result = 'foo'
+ ..error = 'bar';
+ final Object encoded = reply.encode();
+ final SearchReply decoded = SearchReply.decode(encoded);
+ expect(reply.result, decoded.result);
+ expect(reply.error, decoded.error);
+ });
+
+ test('with null value', () {
+ final SearchReply reply = SearchReply()
+ ..result = 'foo'
+ ..error = null;
+ final Object encoded = reply.encode();
+ final SearchReply decoded = SearchReply.decode(encoded);
+ expect(reply.result, decoded.result);
+ expect(reply.error, decoded.error);
+ });
+}
diff --git a/packages/pigeon/pubspec.yaml b/packages/pigeon/pubspec.yaml
index 408779e..e534e2d 100644
--- a/packages/pigeon/pubspec.yaml
+++ b/packages/pigeon/pubspec.yaml
@@ -1,5 +1,5 @@
name: pigeon
-version: 0.1.20 # This must match the version in lib/generator_tools.dart
+version: 0.1.21 # This must match the version in lib/generator_tools.dart
description: Code generator tool to make communication between Flutter and the host platform type-safe and easier.
homepage: https://github.com/flutter/packages/tree/master/packages/pigeon
dependencies:
diff --git a/packages/pigeon/run_tests.sh b/packages/pigeon/run_tests.sh
index c6b5b20..ae5aa1e 100755
--- a/packages/pigeon/run_tests.sh
+++ b/packages/pigeon/run_tests.sh
@@ -111,6 +111,19 @@
pub run pigeon 1> /dev/null
###############################################################################
+# Run unit tests on generated Dart code.
+###############################################################################
+pushd $PWD
+pub run pigeon \
+ --input pigeons/message.dart \
+ --dart_null_safety \
+ --dart_out platform_tests/flutter_null_safe_unit_tests/lib/null_safe_pigeon.dart
+cd platform_tests/flutter_null_safe_unit_tests
+flutter pub get
+flutter test test/null_safe_test.dart
+popd
+
+###############################################################################
# Mock handler flutter tests.
###############################################################################
pushd $PWD
diff --git a/packages/pigeon/test/java_generator_test.dart b/packages/pigeon/test/java_generator_test.dart
index 0334de6..c453231 100644
--- a/packages/pigeon/test/java_generator_test.dart
+++ b/packages/pigeon/test/java_generator_test.dart
@@ -46,7 +46,7 @@
generateJava(javaOptions, root, sink);
final String code = sink.toString();
expect(code, contains('package com.google.foobar;'));
- expect(code, contains('HashMap toMap()'));
+ expect(code, contains('Map<String, Object> toMap()'));
});
test('gen one host api', () {
@@ -242,7 +242,7 @@
generateJava(javaOptions, root, sink);
final String code = sink.toString();
expect(code, contains('public static class Foobar'));
- expect(code, contains('private ArrayList field1;'));
+ expect(code, contains('private List<Object> field1;'));
});
test('gen map', () {
@@ -257,7 +257,7 @@
generateJava(javaOptions, root, sink);
final String code = sink.toString();
expect(code, contains('public static class Foobar'));
- expect(code, contains('private HashMap field1;'));
+ expect(code, contains('private Map<String, Object> field1;'));
});
test('gen nested', () {
@@ -287,7 +287,7 @@
expect(code, contains('public static class Outer'));
expect(code, contains('public static class Nested'));
expect(code, contains('private Nested nested;'));
- expect(code, contains('Nested.fromMap((HashMap)nested);'));
+ expect(code, contains('Nested.fromMap((Map)nested);'));
expect(code, contains('put("nested", nested.toMap());'));
});
diff --git a/packages/pointer_interceptor/CHANGELOG.md b/packages/pointer_interceptor/CHANGELOG.md
index a11d080..06e0c6e 100644
--- a/packages/pointer_interceptor/CHANGELOG.md
+++ b/packages/pointer_interceptor/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.9.0
+
+* Migrates to null safety.
+
## 0.8.0+2
* Use `ElevatedButton` instead of the deprecated `RaisedButton` in example and docs.
diff --git a/packages/pointer_interceptor/example/README.md b/packages/pointer_interceptor/example/README.md
index d4973fd..9fddf8c 100644
--- a/packages/pointer_interceptor/example/README.md
+++ b/packages/pointer_interceptor/example/README.md
@@ -8,7 +8,7 @@
## Running tests
-`flutter drive --target integration_test/widget_test.dart --driver test_driver/integration_test.dart --show-web-server-device -d web-server`
+`flutter drive --target integration_test/widget_test.dart --driver test_driver/integration_test.dart --show-web-server-device -d web-server --web-renderer=html`
The command above will run the integration tests for this package.
diff --git a/packages/pointer_interceptor/example/integration_test/widget_test.dart b/packages/pointer_interceptor/example/integration_test/widget_test.dart
index 59ca9a6..72b02ad 100644
--- a/packages/pointer_interceptor/example/integration_test/widget_test.dart
+++ b/packages/pointer_interceptor/example/integration_test/widget_test.dart
@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// @dart = 2.9
import 'dart:html' as html;
// Imports the Flutter Driver API.
@@ -27,12 +26,12 @@
app.main();
await tester.pumpAndSettle();
- final html.Element element =
+ final html.Element? element =
_getHtmlElementFromFinder(clickableButtonFinder, tester);
- expect(element.tagName.toLowerCase(), 'flt-platform-view');
+ expect(element?.tagName.toLowerCase(), 'flt-platform-view');
- final html.Element platformViewRoot =
- element.shadowRoot.getElementById('background-html-view');
+ final html.Element? platformViewRoot =
+ element?.shadowRoot?.getElementById('background-html-view');
expect(platformViewRoot, isNull);
});
@@ -42,12 +41,12 @@
app.main();
await tester.pumpAndSettle();
- final html.Element element =
+ final html.Element? element =
_getHtmlElementFromFinder(nonClickableButtonFinder, tester);
- expect(element.tagName.toLowerCase(), 'flt-platform-view');
+ expect(element?.tagName.toLowerCase(), 'flt-platform-view');
- final html.Element platformViewRoot =
- element.shadowRoot.getElementById('background-html-view');
+ final html.Element? platformViewRoot =
+ element?.shadowRoot?.getElementById('background-html-view');
expect(platformViewRoot, isNotNull);
});
});
@@ -56,7 +55,7 @@
// This functions locates a widget from a Finder, and asks the browser what's the
// DOM element in the center of the coordinates of the widget. (Returns *which*
// DOM element will handle Mouse interactions first at those coordinates.)
-html.Element _getHtmlElementFromFinder(Finder finder, WidgetTester tester) {
+html.Element? _getHtmlElementFromFinder(Finder finder, WidgetTester tester) {
final Offset point = tester.getCenter(finder);
return html.document.elementFromPoint(point.dx.toInt(), point.dy.toInt());
}
diff --git a/packages/pointer_interceptor/example/lib/main.dart b/packages/pointer_interceptor/example/lib/main.dart
index 4421e79..fd2b539 100644
--- a/packages/pointer_interceptor/example/lib/main.dart
+++ b/packages/pointer_interceptor/example/lib/main.dart
@@ -186,7 +186,7 @@
/// Initialize the videoPlayer, then render the corresponding view...
class HtmlElement extends StatelessWidget {
/// Constructor
- const HtmlElement({this.onClick});
+ const HtmlElement({required this.onClick});
/// A function to run when the element is clicked
final Function onClick;
diff --git a/packages/pointer_interceptor/example/lib/src/shim/dart_ui_fake.dart b/packages/pointer_interceptor/example/lib/src/shim/dart_ui_fake.dart
index d8456c0..787e349 100644
--- a/packages/pointer_interceptor/example/lib/src/shim/dart_ui_fake.dart
+++ b/packages/pointer_interceptor/example/lib/src/shim/dart_ui_fake.dart
@@ -22,7 +22,7 @@
/// Shim for getAssetUrl.
/// https://github.com/flutter/engine/blob/master/lib/web_ui/lib/src/engine/assets.dart#L45
static String getAssetUrl(String asset) {
- return null;
+ return '';
}
}
diff --git a/packages/pointer_interceptor/example/pubspec.yaml b/packages/pointer_interceptor/example/pubspec.yaml
index dbb4f7a..2ed4117 100644
--- a/packages/pointer_interceptor/example/pubspec.yaml
+++ b/packages/pointer_interceptor/example/pubspec.yaml
@@ -4,7 +4,8 @@
version: 1.0.0
environment:
- sdk: ">=2.7.0 <3.0.0"
+ sdk: ">=2.12.0-0 <3.0.0"
+ flutter: ">=1.26.0-0" # For integration_test from sdk
dependencies:
flutter:
diff --git a/packages/pointer_interceptor/lib/src/mobile.dart b/packages/pointer_interceptor/lib/src/mobile.dart
index ef4ef6a..1f561ac 100644
--- a/packages/pointer_interceptor/lib/src/mobile.dart
+++ b/packages/pointer_interceptor/lib/src/mobile.dart
@@ -8,9 +8,9 @@
class PointerInterceptor extends StatelessWidget {
/// Create a `PointerInterceptor` wrapping a `child`.
const PointerInterceptor({
- @required this.child,
+ required this.child,
this.debug = false,
- Key key,
+ Key? key,
}) : super(key: key);
/// The `Widget` that is being wrapped by this `PointerInterceptor`.
diff --git a/packages/pointer_interceptor/lib/src/shim/dart_ui_fake.dart b/packages/pointer_interceptor/lib/src/shim/dart_ui_fake.dart
index d8456c0..787e349 100644
--- a/packages/pointer_interceptor/lib/src/shim/dart_ui_fake.dart
+++ b/packages/pointer_interceptor/lib/src/shim/dart_ui_fake.dart
@@ -22,7 +22,7 @@
/// Shim for getAssetUrl.
/// https://github.com/flutter/engine/blob/master/lib/web_ui/lib/src/engine/assets.dart#L45
static String getAssetUrl(String asset) {
- return null;
+ return '';
}
}
diff --git a/packages/pointer_interceptor/lib/src/web.dart b/packages/pointer_interceptor/lib/src/web.dart
index e2e86e8..f59c4a3 100644
--- a/packages/pointer_interceptor/lib/src/web.dart
+++ b/packages/pointer_interceptor/lib/src/web.dart
@@ -40,9 +40,9 @@
class PointerInterceptor extends StatelessWidget {
/// Creates a PointerInterceptor for the web.
PointerInterceptor({
- @required this.child,
+ required this.child,
this.debug = false,
- Key key,
+ Key? key,
}) : super(key: key) {
if (!_registered) {
_register();
diff --git a/packages/pointer_interceptor/pubspec.yaml b/packages/pointer_interceptor/pubspec.yaml
index 5bf127d..5bea65f 100644
--- a/packages/pointer_interceptor/pubspec.yaml
+++ b/packages/pointer_interceptor/pubspec.yaml
@@ -1,10 +1,10 @@
name: pointer_interceptor
description: A widget to prevent clicks from being swallowed by underlying HtmlElementViews on the web.
-version: 0.8.0+2
repository: https://github.com/flutter/packages
+version: 0.9.0
environment:
- sdk: ">=2.7.0 <3.0.0"
+ sdk: ">=2.12.0-0 <3.0.0"
flutter: ">=1.17.0"
dependencies:
diff --git a/packages/xdg_directories/CHANGELOG.md b/packages/xdg_directories/CHANGELOG.md
index ce6349a..1a525f0 100644
--- a/packages/xdg_directories/CHANGELOG.md
+++ b/packages/xdg_directories/CHANGELOG.md
@@ -1,20 +1,15 @@
-## [0.2.0-nullsafety.1] - Fix getUserDirectory
-
-* Fixes a regression due to the stdoutEncoding change
- in the null-safety migration.
-
-## [0.2.0-nullsafety.0] - Migrated to null safety
+## 0.2.0
* Migrated to null safety.
-## [0.1.2] - Reduce dependencies on external libraries.
+## 0.1.2
* Broaden dependencies to allow nullsafety version of process, meta, and path to be OK.
-## [0.1.1] - Reduce dependencies on external libraries.
+## 0.1.1
* Remove flutter, flutter_test from pubspec dependencies.
-## [0.1.0] - Initial Release
+## 0.1.0
* Initial release includes all the features described in the README.md
diff --git a/packages/xdg_directories/pubspec.yaml b/packages/xdg_directories/pubspec.yaml
index 95054e3..197813e 100644
--- a/packages/xdg_directories/pubspec.yaml
+++ b/packages/xdg_directories/pubspec.yaml
@@ -1,16 +1,15 @@
name: xdg_directories
description: A Dart package for reading XDG directory configuration information on Linux.
-version: 0.2.0-nullsafety.1
+version: 0.2.0
homepage: https://github.com/flutter/packages/tree/master/packages/xdg_directories
environment:
sdk: ">=2.12.0-0 <3.0.0"
dependencies:
- meta: ^1.3.0-nullsafety.6
- path: ^1.8.0-nullsafety.3
- process: ^4.0.0-nullsafety.4
+ meta: ^1.3.0
+ path: ^1.8.0
+ process: ^4.0.0
dev_dependencies:
- mockito: ^5.0.0-nullsafety.1
- test: ^1.16.0-nullsafety.13
+ test: ^1.16.0
diff --git a/packages/xdg_directories/test/xdg_directories_test.dart b/packages/xdg_directories/test/xdg_directories_test.dart
index 255a69e..c082726 100644
--- a/packages/xdg_directories/test/xdg_directories_test.dart
+++ b/packages/xdg_directories/test/xdg_directories_test.dart
@@ -5,9 +5,9 @@
import 'dart:convert';
import 'dart:io';
+import 'package:test/fake.dart';
import 'package:test/test.dart';
import 'package:path/path.dart' as path;
-import 'package:mockito/mockito.dart' show Fake;
import 'package:process/process.dart';
import 'package:xdg_directories/xdg_directories.dart' as xdg;