diff --git a/.cirrus.yml b/.cirrus.yml index 453a2ce0ac2c..4ec73ea3f24c 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -39,8 +39,16 @@ task: - flutter channel $CHANNEL - ./script/incremental_build.sh test - name: analyze + env: + matrix: + CHANNEL: "master" + CHANNEL: "stable" script: ./script/incremental_build.sh analyze - name: build_all_plugins_apk + env: + matrix: + CHANNEL: "master" + CHANNEL: "stable" script: # TODO(jackson): Allow web plugins once supported on stable # https://github.com/flutter/flutter/issues/42864 @@ -144,6 +152,10 @@ task: - xcrun simctl create Flutter-iPhone com.apple.CoreSimulator.SimDeviceType.iPhone-X com.apple.CoreSimulator.SimRuntime.iOS-13-3 | xargs xcrun simctl boot matrix: - name: build_all_plugins_ipa + env: + matrix: + CHANNEL: "master" + CHANNEL: "stable" script: # TODO(jackson): Allow web plugins once supported on stable # https://github.com/flutter/flutter/issues/42864 diff --git a/packages/android_intent/test/android_intent_test.dart b/packages/android_intent/test/android_intent_test.dart index b0fa48e22fee..ad0eae3b662d 100644 --- a/packages/android_intent/test/android_intent_test.dart +++ b/packages/android_intent/test/android_intent_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. +// @dart = 2.9 + import 'package:android_intent/flag.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -11,7 +13,8 @@ import 'package:platform/platform.dart'; void main() { AndroidIntent androidIntent; - late MockMethodChannel mockChannel; + MockMethodChannel mockChannel; + setUp(() { mockChannel = MockMethodChannel(); when(mockChannel.invokeMethod('canResolveActivity', any)) diff --git a/packages/flutter_plugin_android_lifecycle/example/integration_test/flutter_plugin_android_lifecycle_test.dart b/packages/flutter_plugin_android_lifecycle/example/integration_test/flutter_plugin_android_lifecycle_test.dart index 1405ab69153c..ba67043bcf43 100644 --- a/packages/flutter_plugin_android_lifecycle/example/integration_test/flutter_plugin_android_lifecycle_test.dart +++ b/packages/flutter_plugin_android_lifecycle/example/integration_test/flutter_plugin_android_lifecycle_test.dart @@ -2,6 +2,8 @@ // 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. +// @dart = 2.9 + import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; import 'package:flutter_plugin_android_lifecycle_example/main.dart'; diff --git a/packages/flutter_plugin_android_lifecycle/example/lib/main.dart b/packages/flutter_plugin_android_lifecycle/example/lib/main.dart index 6dfe523a0ae1..eb82aacd0237 100644 --- a/packages/flutter_plugin_android_lifecycle/example/lib/main.dart +++ b/packages/flutter_plugin_android_lifecycle/example/lib/main.dart @@ -1,3 +1,7 @@ +// Copyright 2019, the Chromium project authors. Please see the AUTHORS file +// 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. + // ignore_for_file: public_member_api_docs import 'package:flutter/material.dart'; diff --git a/packages/flutter_plugin_android_lifecycle/example/pubspec.yaml b/packages/flutter_plugin_android_lifecycle/example/pubspec.yaml index 2532ab047dcc..4643317c1951 100644 --- a/packages/flutter_plugin_android_lifecycle/example/pubspec.yaml +++ b/packages/flutter_plugin_android_lifecycle/example/pubspec.yaml @@ -1,23 +1,21 @@ name: flutter_plugin_android_lifecycle_example description: Demonstrates how to use the flutter_plugin_android_lifecycle plugin. -publish_to: 'none' - -environment: - sdk: ">=2.12.0-0 <3.0.0" dependencies: flutter: sdk: flutter - integration_test: - path: ../../integration_test + flutter_plugin_android_lifecycle: + path: ../ dev_dependencies: + integration_test: + path: ../../integration_test flutter_test: sdk: flutter pedantic: ^1.8.0 - flutter_plugin_android_lifecycle: - path: ../ +environment: + sdk: ">=2.12.0-0 <3.0.0" flutter: uses-material-design: true diff --git a/packages/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/MainActivityTest.java b/packages/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/FlutterFragmentActivityTest.java similarity index 100% rename from packages/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/MainActivityTest.java rename to packages/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/FlutterFragmentActivityTest.java diff --git a/packages/local_auth/example/lib/main.dart b/packages/local_auth/example/lib/main.dart index 06e33b9853be..241593a08b6a 100644 --- a/packages/local_auth/example/lib/main.dart +++ b/packages/local_auth/example/lib/main.dart @@ -21,16 +21,17 @@ class MyApp extends StatefulWidget { class _MyAppState extends State { final LocalAuthentication auth = LocalAuthentication(); - bool _canCheckBiometrics; - List _availableBiometrics; + late bool _canCheckBiometrics; + late List _availableBiometrics; String _authorized = 'Not Authorized'; bool _isAuthenticating = false; Future _checkBiometrics() async { - bool canCheckBiometrics; + late bool canCheckBiometrics; try { canCheckBiometrics = await auth.canCheckBiometrics; } on PlatformException catch (e) { + canCheckBiometrics = false; print(e); } if (!mounted) return; @@ -41,10 +42,11 @@ class _MyAppState extends State { } Future _getAvailableBiometrics() async { - List availableBiometrics; + late List availableBiometrics; try { availableBiometrics = await auth.getAvailableBiometrics(); } on PlatformException catch (e) { + availableBiometrics = []; print(e); } if (!mounted) return; diff --git a/packages/local_auth/example/pubspec.yaml b/packages/local_auth/example/pubspec.yaml index 0861c51adbc6..9c7b91e672e6 100644 --- a/packages/local_auth/example/pubspec.yaml +++ b/packages/local_auth/example/pubspec.yaml @@ -18,5 +18,5 @@ flutter: uses-material-design: true environment: - sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.12.0-0 <3.0.0" flutter: ">=1.12.13+hotfix.5 <2.0.0" diff --git a/packages/local_auth/integration_test/local_auth_test.dart b/packages/local_auth/integration_test/local_auth_test.dart index 47e5dfa67912..c09810032461 100644 --- a/packages/local_auth/integration_test/local_auth_test.dart +++ b/packages/local_auth/integration_test/local_auth_test.dart @@ -1,3 +1,9 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// @dart = 2.9 + import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; diff --git a/packages/share/integration_test/share_test.dart b/packages/share/integration_test/share_test.dart index 08a19ce2c27b..7b66480d0681 100644 --- a/packages/share/integration_test/share_test.dart +++ b/packages/share/integration_test/share_test.dart @@ -2,6 +2,8 @@ // 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. +// @dart = 2.9 + import 'package:flutter_test/flutter_test.dart'; import 'package:share/share.dart'; import 'package:integration_test/integration_test.dart'; diff --git a/packages/share/test/share_test.dart b/packages/share/test/share_test.dart index fa9f980beae3..d00867b19452 100644 --- a/packages/share/test/share_test.dart +++ b/packages/share/test/share_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. +// @dart = 2.9 + import 'dart:io'; import 'dart:ui'; @@ -15,7 +17,7 @@ import 'package:flutter/services.dart'; void main() { TestWidgetsFlutterBinding.ensureInitialized(); - late MockMethodChannel mockChannel; + MockMethodChannel mockChannel; setUp(() { mockChannel = MockMethodChannel(); diff --git a/packages/webview_flutter/CHANGELOG.md b/packages/webview_flutter/CHANGELOG.md index 19cacb6a6e90..867ea1757985 100644 --- a/packages/webview_flutter/CHANGELOG.md +++ b/packages/webview_flutter/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.0-nullsafety.3 + +* Fix `onWebResourceError` on iOS. + ## 2.0.0-nullsafety.2 * Fix outdated links across a number of markdown files ([#3276](https://github.com/flutter/plugins/pull/3276)) diff --git a/packages/webview_flutter/example/integration_test/webview_flutter_test.dart b/packages/webview_flutter/example/integration_test/webview_flutter_test.dart index 86cf8ab73e05..5f39cc3d86d2 100644 --- a/packages/webview_flutter/example/integration_test/webview_flutter_test.dart +++ b/packages/webview_flutter/example/integration_test/webview_flutter_test.dart @@ -2,6 +2,8 @@ // 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. +// @dart = 2.9 + import 'dart:async'; import 'dart:convert'; import 'dart:io'; @@ -358,12 +360,12 @@ void main() { videoTestBase64 = base64Encode(const Utf8Encoder().convert(videoTest)); }); - test('Auto media playback', () async { + testWidgets('Auto media playback', (WidgetTester tester) async { Completer controllerCompleter = Completer(); Completer pageLoaded = Completer(); - await pumpWidget( + await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, child: WebView( @@ -390,7 +392,7 @@ void main() { pageLoaded = Completer(); // We change the key to re-create a new webview as we change the initialMediaPlaybackPolicy - await pumpWidget( + await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, child: WebView( @@ -414,15 +416,16 @@ void main() { isPaused = await controller.evaluateJavascript('isPaused();'); expect(isPaused, _webviewBool(true)); - }); + }, skip: true /* https://github.com/flutter/flutter/issues/72572 */); - test('Changes to initialMediaPlaybackPolicy are ignored', () async { + testWidgets('Changes to initialMediaPlaybackPolicy are ignored', + (WidgetTester tester) async { final Completer controllerCompleter = Completer(); Completer pageLoaded = Completer(); final GlobalKey key = GlobalKey(); - await pumpWidget( + await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, child: WebView( @@ -447,7 +450,7 @@ void main() { pageLoaded = Completer(); - await pumpWidget( + await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, child: WebView( @@ -472,14 +475,15 @@ void main() { isPaused = await controller.evaluateJavascript('isPaused();'); expect(isPaused, _webviewBool(false)); - }); + }, skip: true /* https://github.com/flutter/flutter/issues/72572 */); - test('Video plays inline when allowsInlineMediaPlayback is true', () async { + testWidgets('Video plays inline when allowsInlineMediaPlayback is true', + (WidgetTester tester) async { Completer controllerCompleter = Completer(); Completer pageLoaded = Completer(); - await pumpWidget( + await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, child: WebView( @@ -507,7 +511,7 @@ void main() { controllerCompleter = Completer(); pageLoaded = Completer(); - await pumpWidget( + await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, child: WebView( @@ -531,7 +535,7 @@ void main() { isFullScreen = await controller.evaluateJavascript('isFullScreen();'); expect(isFullScreen, _webviewBool(true)); - }); + }, skip: true /* https://github.com/flutter/flutter/issues/72572 */); }); group('Audio playback policy', () { @@ -631,7 +635,7 @@ void main() { isPaused = await controller.evaluateJavascript('isPaused();'); expect(isPaused, _webviewBool(true)); - }); + }, skip: true /* https://github.com/flutter/flutter/issues/72572 */); testWidgets('Changes to initialMediaPlaybackPolocy are ignored', (WidgetTester tester) async { @@ -700,7 +704,7 @@ void main() { isPaused = await controller.evaluateJavascript('isPaused();'); expect(isPaused, _webviewBool(false)); - }); + }, skip: true /* https://github.com/flutter/flutter/issues/72572 */); }); testWidgets('getTitle', (WidgetTester tester) async { diff --git a/packages/webview_flutter/example/lib/main.dart b/packages/webview_flutter/example/lib/main.dart index 2a4b652d2658..c7f42ac2bf66 100644 --- a/packages/webview_flutter/example/lib/main.dart +++ b/packages/webview_flutter/example/lib/main.dart @@ -105,7 +105,7 @@ class _WebViewExampleState extends State { if (controller.hasData) { return FloatingActionButton( onPressed: () async { - final String url = await controller.data.currentUrl(); + final String url = (await controller.data!.currentUrl())!; // ignore: deprecated_member_use Scaffold.of(context).showSnackBar( SnackBar(content: Text('Favorited $url')), @@ -145,25 +145,25 @@ class SampleMenu extends StatelessWidget { onSelected: (MenuOptions value) { switch (value) { case MenuOptions.showUserAgent: - _onShowUserAgent(controller.data, context); + _onShowUserAgent(controller.data!, context); break; case MenuOptions.listCookies: - _onListCookies(controller.data, context); + _onListCookies(controller.data!, context); break; case MenuOptions.clearCookies: _onClearCookies(context); break; case MenuOptions.addToCache: - _onAddToCache(controller.data, context); + _onAddToCache(controller.data!, context); break; case MenuOptions.listCache: - _onListCache(controller.data, context); + _onListCache(controller.data!, context); break; case MenuOptions.clearCache: - _onClearCache(controller.data, context); + _onClearCache(controller.data!, context); break; case MenuOptions.navigationDelegate: - _onNavigationDelegateExample(controller.data, context); + _onNavigationDelegateExample(controller.data!, context); break; } }, @@ -299,7 +299,7 @@ class NavigationControls extends StatelessWidget { (BuildContext context, AsyncSnapshot snapshot) { final bool webViewReady = snapshot.connectionState == ConnectionState.done; - final WebViewController controller = snapshot.data; + final WebViewController controller = snapshot.data!; return Row( children: [ IconButton( diff --git a/packages/webview_flutter/example/pubspec.yaml b/packages/webview_flutter/example/pubspec.yaml index 543e7fd86971..1ace8afe400f 100644 --- a/packages/webview_flutter/example/pubspec.yaml +++ b/packages/webview_flutter/example/pubspec.yaml @@ -2,7 +2,7 @@ name: webview_flutter_example description: Demonstrates how to use the webview_flutter plugin. environment: - sdk: ">=2.0.0-dev.68.0 <3.0.0" + sdk: ">=2.12.0-0 <3.0.0" dependencies: flutter: diff --git a/packages/webview_flutter/example/test_driver/integration_test.dart b/packages/webview_flutter/example/test_driver/integration_test.dart index 7a2c21338786..a8a56aa90f6a 100644 --- a/packages/webview_flutter/example/test_driver/integration_test.dart +++ b/packages/webview_flutter/example/test_driver/integration_test.dart @@ -2,6 +2,8 @@ // 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. +// @dart = 2.9 + import 'dart:async'; import 'dart:convert'; import 'dart:io'; diff --git a/packages/webview_flutter/lib/src/webview_method_channel.dart b/packages/webview_flutter/lib/src/webview_method_channel.dart index b38d65acb486..54ab647cdc04 100644 --- a/packages/webview_flutter/lib/src/webview_method_channel.dart +++ b/packages/webview_flutter/lib/src/webview_method_channel.dart @@ -48,7 +48,8 @@ class MethodChannelWebViewPlatform implements WebViewPlatformController { WebResourceError( errorCode: call.arguments['errorCode']!, description: call.arguments['description']!, - failingUrl: call.arguments['failingUrl']!, + // iOS doesn't support `failingUrl`. + failingUrl: call.arguments['failingUrl'], domain: call.arguments['domain'], errorType: call.arguments['errorType'] == null ? null diff --git a/packages/webview_flutter/pubspec.yaml b/packages/webview_flutter/pubspec.yaml index b2fbfc1110c5..8bdd790e5e36 100644 --- a/packages/webview_flutter/pubspec.yaml +++ b/packages/webview_flutter/pubspec.yaml @@ -1,6 +1,6 @@ name: webview_flutter description: A Flutter plugin that provides a WebView widget on Android and iOS. -version: 2.0.0-nullsafety.2 +version: 2.0.0-nullsafety.3 homepage: https://github.com/flutter/plugins/tree/master/packages/webview_flutter environment: diff --git a/script/build_all_plugins_app.sh b/script/build_all_plugins_app.sh index f2897f8aa9a2..ca97c05f8ee4 100755 --- a/script/build_all_plugins_app.sh +++ b/script/build_all_plugins_app.sh @@ -1,10 +1,16 @@ #!/bin/bash +# Usage: +# +# ./script/build_all_plugins_app.sh apk +# ./script/build_all_plugins_app.sh ios + # This script builds the app in flutter/plugins/example/all_plugins to make # sure all first party plugins can be compiled together. # So that users can run this script from anywhere and it will work as expected. readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" > /dev/null && pwd)" + readonly REPO_DIR="$(dirname "$SCRIPT_DIR")" source "$SCRIPT_DIR/common.sh" @@ -23,6 +29,7 @@ readonly EXCLUDED_PLUGINS_LIST=( "google_sign_in_platform_interface" "google_sign_in_web" "image_picker_platform_interface" + "local_auth" # flutter_plugin_android_lifecycle conflict "instrumentation_adapter" "path_provider_linux" "path_provider_macos" @@ -46,7 +53,7 @@ readonly EXCLUDED=$(IFS=, ; echo "${EXCLUDED_PLUGINS_LIST[*]}") ALL_EXCLUDED=($EXCLUDED) # Exclude nnbd plugins from stable. -if [[ "$CHANNEL" -eq "stable" ]]; then +if [ "$CHANNEL" == "stable" ]; then ALL_EXCLUDED=("$EXCLUDED,$EXCLUDED_PLUGINS_FROM_STABLE") fi diff --git a/script/incremental_build.sh b/script/incremental_build.sh index f54f90b0669c..3911f0a6e9c8 100755 --- a/script/incremental_build.sh +++ b/script/incremental_build.sh @@ -16,7 +16,7 @@ fi # Plugins that are excluded from this task. ALL_EXCLUDED=("") # Exclude nnbd plugins from stable. -if [[ "$CHANNEL" -eq "stable" ]]; then +if [ "$CHANNEL" == "stable" ]; then ALL_EXCLUDED=($EXCLUDED_PLUGINS_FROM_STABLE) echo "Excluding the following plugins: $ALL_EXCLUDED" fi